<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<!-- 
	Copyright (C) 2007, 2008, 2009, 2010, 2011. PARP Research Group.
	<http://perception.inf.um.es>
	University of Murcia, Spain.

	This file is part of the QVision library.

	QVision is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as
	published by the Free Software Foundation, version 3 of the License.

	QVision is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with QVision. If not, see <http://www.gnu.org/licenses/>.
-->

<html><head><meta http-equiv="content-Type" content="text/html;charset=UTF-8">
<title>QVision: Qt&#39;s Image, Video and Computer Vision Library</title>
<meta name="title" content="QVision" />
<meta name="dc.title" content="QVision" />
<meta name="url" content="http://perception.inf.um.es/QVision" />
<meta name="author" content="PARP Research Group - http://perception.inf.um.es" />
<meta name="revisit-after" content="30 DAYS"/>
<meta name="robots" content="index,follow"/>
<meta name="classification" content="*">
<meta name="rating" content="Safe For Kids">
<meta name="distribution" content="GLOBAL"/>
<meta name="description" content="Qt's Image, Video and Computer Vision Library"/>
<meta name="page-topic" content="Computer Vision research and prototype programming"/>
<meta name="geo.country" content="ES" />

<!--
Keywords:
By license:		open source, gnu, lgpl, gpl, free
By theme:		computer vision, image processing, robotics, programming, source, development
By usage:		library, toolkit, framework, prototype, application
By programming specs:	object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping
Interoperability with:	Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack
Functionallity:		image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface
Main data-types:	matrix, vector, tensor, quaternion, image, polyline
Video sources:		webcam, camera, stream
Devices:		embedded, desktop computer, laptop, mini-laptop
Authors:		PARP research group. University of Murcia, Spain.
-->

<meta name="keywords" content="augmented reality, sfm, structure from motion, open source, gnu, lgpl, gpl, free, computer vision, image processing, robotics, programming, source, development, library, toolkit, framework, prototype, application, object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping, Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack, image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface, matrix, vector, tensor, quaternion, image, polyline, webcam, camera, stream, embedded, desktop computer, laptop, mini-laptop, University of Murcia, Spain, PARP research group, vision por computador"/>
<meta http-equiv="keywords" content="augmented reality, sfm, structure from motion, open source, gnu, lgpl, gpl, free, computer vision, image processing, robotics, programming, source, development, library, toolkit, framework, prototype, application, object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping, Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack, image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface, matrix, vector, tensor, quaternion, image, polyline, webcam, camera, stream, embedded, desktop computer, laptop, mini-laptop, University of Murcia, Spain, PARP research group, vision por computador"/>
<meta http-equiv="pragma" content="no-cache"/>
<meta http-equiv="title" content="QVision"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="tabs.css" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="favicon.ico" />
</head><body>

<table width="100%"><tr>
	<td><a href="http://perception.inf.um.es/"><img src="parp.png" border="0" /> <big>PARP Research Group</big></a></td>
	<td align="right"><a href="http://www.um.es/"><big>Universidad de Murcia</big> <img src="um.png" border="0" /></a></td>
</tr></table>

<hr /><br />

<table width="95%" align="center"><tr><td>

<!-- Generated by Doxygen 1.6.3 -->
<script type="text/javascript"><!--
var searchBox = new SearchBox("searchBox", "search",false,'Search');
--></script>
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="pages.html"><span>Related&nbsp;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
      <li>
        <div id="MSearchBox" class="MSearchBoxInactive">
          <form id="FSearchBox" action="search.php" method="get">
            <img id="MSearchSelect" src="search/search.png" alt=""/>
            <input type="text" id="MSearchField" name="query" value="Search" size="20" accesskey="S" 
                   onfocus="searchBox.OnSearchFieldFocus(true)" 
                   onblur="searchBox.OnSearchFieldFocus(false)"/>
          </form>
        </div>
      </li>
    </ul>
  </div>
  <div class="tabs">
    <ul>
      <li><a href="files.html"><span>File&nbsp;List</span></a></li>
      <li><a href="globals.html"><span>File&nbsp;Members</span></a></li>
    </ul>
  </div>
<h1>src/qvip/qvip.cpp</h1><a href="qvip_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
<a name="l00002"></a>00002 <span class="comment"> *      Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012. PARP Research Group.</span>
<a name="l00003"></a>00003 <span class="comment"> *      &lt;http://perception.inf.um.es&gt;</span>
<a name="l00004"></a>00004 <span class="comment"> *      University of Murcia, Spain.</span>
<a name="l00005"></a>00005 <span class="comment"> *</span>
<a name="l00006"></a>00006 <span class="comment"> *      This file is part of the QVision library.</span>
<a name="l00007"></a>00007 <span class="comment"> *</span>
<a name="l00008"></a>00008 <span class="comment"> *      QVision is free software: you can redistribute it and/or modify</span>
<a name="l00009"></a>00009 <span class="comment"> *      it under the terms of the GNU Lesser General Public License as</span>
<a name="l00010"></a>00010 <span class="comment"> *      published by the Free Software Foundation, version 3 of the License.</span>
<a name="l00011"></a>00011 <span class="comment"> *</span>
<a name="l00012"></a>00012 <span class="comment"> *      QVision is distributed in the hope that it will be useful,</span>
<a name="l00013"></a>00013 <span class="comment"> *      but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<a name="l00014"></a>00014 <span class="comment"> *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<a name="l00015"></a>00015 <span class="comment"> *      GNU Lesser General Public License for more details.</span>
<a name="l00016"></a>00016 <span class="comment"> *</span>
<a name="l00017"></a>00017 <span class="comment"> *      You should have received a copy of the GNU Lesser General Public</span>
<a name="l00018"></a>00018 <span class="comment"> *      License along with QVision. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<a name="l00019"></a>00019 <span class="comment"> */</span>
<a name="l00020"></a>00020 
<a name="l00024"></a>00024 
<a name="l00025"></a>00025 <span class="preprocessor">#include &lt;stdio.h&gt;</span>
<a name="l00026"></a>00026 <span class="preprocessor">#include &lt;stdlib.h&gt;</span>
<a name="l00027"></a>00027 <span class="preprocessor">#include &lt;float.h&gt;</span>
<a name="l00028"></a>00028 <span class="preprocessor">#include &lt;iostream&gt;</span>
<a name="l00029"></a>00029 
<a name="l00030"></a>00030 <span class="preprocessor">#include &lt;qvip.h&gt;</span>
<a name="l00031"></a>00031 <span class="preprocessor">#include &lt;qvmath.h&gt;</span>
<a name="l00032"></a>00032 <span class="preprocessor">#include &lt;<a class="code" href="qvdefines_8h.html" title="File from the QVision library.">qvdefines.h</a>&gt;</span>
<a name="l00033"></a>00033 <span class="preprocessor">#include &lt;qvmatrixalgebra.h&gt;</span>
<a name="l00034"></a>00034 <span class="preprocessor">#include &lt;QVPolyline&gt;</span>
<a name="l00035"></a>00035 <span class="preprocessor">#include &lt;QVPolylineF&gt;</span>
<a name="l00036"></a>00036 <span class="preprocessor">#include &lt;QList&gt;</span>
<a name="l00037"></a>00037 
<a name="l00038"></a>00038 <span class="preprocessor">#include&lt;qvip/fast-C-src-2.1/fast.h&gt;</span>
<a name="l00039"></a>00039 
<a name="l00040"></a>00040 <span class="preprocessor">#ifdef QVIPP</span>
<a name="l00041"></a>00041 <span class="preprocessor"></span><span class="preprocessor">#include &lt;qvipp.h&gt;</span>
<a name="l00042"></a>00042 <span class="preprocessor">#endif</span>
<a name="l00043"></a>00043 <span class="preprocessor"></span>
<a name="l00044"></a>00044 <span class="preprocessor">#ifndef QVIPP</span>
<a name="l00045"></a>00045 <span class="preprocessor"></span>QVector&lt;int&gt; <a class="code" href="group__qvipp.html#gae25c99f8b8e1975910a913eaa8d41d96" title="Calculates frequency histogram for a given set of values, for a QVImageThis function...">HistogramRange</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> &amp;src)
<a name="l00046"></a>00046         {
<a name="l00047"></a>00047         QVector&lt; int &gt; result(256);
<a name="l00048"></a>00048 
<a name="l00049"></a>00049         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(uChar,src);
<a name="l00050"></a>00050         <span class="keywordflow">for</span>(uInt row = 0; row &lt; src.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>(); row++)
<a name="l00051"></a>00051                 <span class="keywordflow">for</span>(uInt col = 0; col &lt; src.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(); col++)
<a name="l00052"></a>00052                         result[<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(src, col, row,0)]++;
<a name="l00053"></a>00053 
<a name="l00054"></a>00054         <span class="keywordflow">return</span> result;
<a name="l00055"></a>00055         }
<a name="l00056"></a>00056 <span class="preprocessor">#endif</span>
<a name="l00057"></a>00057 <span class="preprocessor"></span>
<a name="l00058"></a><a class="code" href="group__qvip.html#ga192921df3cd4daafb183772dc960d138">00058</a> QVector&lt; QVector&lt; QPoint &gt; &gt; <a class="code" href="group__qvip.html#ga192921df3cd4daafb183772dc960d138" title="Sorts pixels in an image, given their gray-scale value.This function uses the Counting...">CountingSort</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> &amp;image)
<a name="l00059"></a>00059         {
<a name="l00060"></a>00060         QVector&lt; QVector &lt;QPoint&gt; &gt; result(256);
<a name="l00061"></a>00061         <span class="keyword">const</span> QVector&lt;int&gt; histogram = <a class="code" href="group__qvipp.html#gae25c99f8b8e1975910a913eaa8d41d96" title="Calculates frequency histogram for a given set of values, for a QVImageThis function...">HistogramRange</a>(image);
<a name="l00062"></a>00062 
<a name="l00063"></a>00063         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> k=0; k&lt;256; k++)
<a name="l00064"></a>00064                 result[k].reserve(histogram[k]);
<a name="l00065"></a>00065 
<a name="l00066"></a>00066         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(uChar,image);
<a name="l00067"></a>00067         <span class="keywordflow">for</span>(uInt row = 0; row &lt; image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>(); row++)
<a name="l00068"></a>00068                 <span class="keywordflow">for</span>(uInt col = 0; col &lt; image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(); col++)
<a name="l00069"></a>00069                         result[<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, col, row,0)].append(QPoint(col, row));
<a name="l00070"></a>00070         
<a name="l00071"></a>00071         <span class="keywordflow">return</span> result;
<a name="l00072"></a>00072         }
<a name="l00073"></a>00073 
<a name="l00074"></a>00074 QList&lt;QPointF&gt; getLocalExtremaPixels(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> responseImg, <span class="keyword">const</span> <span class="keywordtype">int</span> threshold)
<a name="l00075"></a>00075         {
<a name="l00076"></a>00076         <span class="keyword">const</span> uChar     *imgData = responseImg.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>();
<a name="l00077"></a>00077         <span class="keyword">const</span> <span class="keywordtype">int</span>       imgStep = responseImg.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>();
<a name="l00078"></a>00078         <span class="keyword">const</span> <span class="keywordtype">int</span>       minX = responseImg.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().x(),
<a name="l00079"></a>00079                         maxX = minX + responseImg.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().width(),
<a name="l00080"></a>00080                         minY = responseImg.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().y(),
<a name="l00081"></a>00081                         maxY = minY + responseImg.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().height();
<a name="l00082"></a>00082                         
<a name="l00083"></a>00083         QList&lt;QPointF&gt; pointsHi;
<a name="l00084"></a>00084         <span class="keyword">const</span> <span class="keywordtype">int</span> imgStepX2 = imgStep*2;
<a name="l00085"></a>00085         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = minY + 2; i &lt; maxY-2; i++)
<a name="l00086"></a>00086                 {
<a name="l00087"></a>00087                 <span class="keyword">const</span> uChar *rowData = imgData + i*imgStep;
<a name="l00088"></a>00088                 <span class="comment">//uChar *gaussRowData = gaussData + i*gaussStep;</span>
<a name="l00089"></a>00089                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j = minX + 2; j &lt; maxX-2; j++)
<a name="l00090"></a>00090                         <span class="keywordflow">if</span> (rowData[j] &gt; threshold)
<a name="l00091"></a>00091                                 {
<a name="l00092"></a>00092                                 <span class="keyword">const</span> uChar value = rowData[j];
<a name="l00093"></a>00093 
<a name="l00094"></a>00094                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-1])
<a name="l00095"></a>00095                                         <span class="keywordflow">continue</span>;
<a name="l00096"></a>00096                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+1])
<a name="l00097"></a>00097                                         <span class="keywordflow">continue</span>;
<a name="l00098"></a>00098                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+imgStep])
<a name="l00099"></a>00099                                         <span class="keywordflow">continue</span>;
<a name="l00100"></a>00100                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-imgStep])
<a name="l00101"></a>00101                                         <span class="keywordflow">continue</span>;
<a name="l00102"></a>00102                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-1+imgStep])
<a name="l00103"></a>00103                                         <span class="keywordflow">continue</span>;
<a name="l00104"></a>00104                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+1+imgStep])
<a name="l00105"></a>00105                                         <span class="keywordflow">continue</span>;
<a name="l00106"></a>00106                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-1-imgStep])
<a name="l00107"></a>00107                                         <span class="keywordflow">continue</span>;
<a name="l00108"></a>00108                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+1-imgStep])
<a name="l00109"></a>00109                                         <span class="keywordflow">continue</span>;
<a name="l00110"></a>00110 
<a name="l00111"></a>00111                                 <span class="comment">// ---------------------------------</span>
<a name="l00112"></a>00112                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-2])
<a name="l00113"></a>00113                                         <span class="keywordflow">continue</span>;
<a name="l00114"></a>00114                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+2])
<a name="l00115"></a>00115                                         <span class="keywordflow">continue</span>;
<a name="l00116"></a>00116                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+imgStepX2])
<a name="l00117"></a>00117                                         <span class="keywordflow">continue</span>;
<a name="l00118"></a>00118                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-imgStepX2])
<a name="l00119"></a>00119                                         <span class="keywordflow">continue</span>;
<a name="l00120"></a>00120                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-2+imgStepX2])
<a name="l00121"></a>00121                                         <span class="keywordflow">continue</span>;
<a name="l00122"></a>00122                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+2+imgStepX2])
<a name="l00123"></a>00123                                         <span class="keywordflow">continue</span>;
<a name="l00124"></a>00124                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-2-imgStepX2])
<a name="l00125"></a>00125                                         <span class="keywordflow">continue</span>;
<a name="l00126"></a>00126                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+2-imgStepX2])
<a name="l00127"></a>00127                                         <span class="keywordflow">continue</span>;
<a name="l00128"></a>00128 
<a name="l00129"></a>00129                                 <span class="comment">// ---------------------------------</span>
<a name="l00130"></a>00130                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-2+imgStep])
<a name="l00131"></a>00131                                         <span class="keywordflow">continue</span>;
<a name="l00132"></a>00132                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-2-imgStep])
<a name="l00133"></a>00133                                         <span class="keywordflow">continue</span>;
<a name="l00134"></a>00134                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+2+imgStep])
<a name="l00135"></a>00135                                         <span class="keywordflow">continue</span>;
<a name="l00136"></a>00136                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+2-imgStep])
<a name="l00137"></a>00137                                         <span class="keywordflow">continue</span>;
<a name="l00138"></a>00138                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+1+imgStepX2])
<a name="l00139"></a>00139                                         <span class="keywordflow">continue</span>;
<a name="l00140"></a>00140                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-1+imgStepX2])
<a name="l00141"></a>00141                                         <span class="keywordflow">continue</span>;
<a name="l00142"></a>00142                                 <span class="keywordflow">if</span> (value &lt;= rowData[j+1+imgStepX2])
<a name="l00143"></a>00143                                         <span class="keywordflow">continue</span>;
<a name="l00144"></a>00144                                 <span class="keywordflow">if</span> (value &lt;= rowData[j-1+imgStepX2])
<a name="l00145"></a>00145                                         <span class="keywordflow">continue</span>;
<a name="l00146"></a>00146 
<a name="l00147"></a>00147                                 pointsHi &lt;&lt; QPointF(j+2,i+2);
<a name="l00148"></a>00148                                 }
<a name="l00149"></a>00149                 }
<a name="l00150"></a>00150         <span class="keywordflow">return</span> pointsHi;
<a name="l00151"></a>00151         }
<a name="l00152"></a>00152 
<a name="l00153"></a>00153 <span class="keywordtype">double</span> ShiTomasiScore(  <span class="keyword">const</span> uChar *imagePtr, <span class="keyword">const</span> <span class="keywordtype">int</span> imageStep,
<a name="l00154"></a>00154                         <span class="keyword">const</span> <span class="keywordtype">int</span> x, <span class="keyword">const</span> <span class="keywordtype">int</span> y,
<a name="l00155"></a>00155                         <span class="keyword">const</span> <span class="keywordtype">int</span> nHalfBoxSize)
<a name="l00156"></a>00156         {
<a name="l00157"></a>00157         <span class="keywordtype">float</span> dXX = 0.0, dYY = 0.0, dXY = 0.0;
<a name="l00158"></a>00158           
<a name="l00159"></a>00159         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> ir_y = y - nHalfBoxSize; ir_y &lt;= y + nHalfBoxSize; ir_y++)
<a name="l00160"></a>00160                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> ir_x = x - nHalfBoxSize; ir_x &lt;= x + nHalfBoxSize; ir_x++)
<a name="l00161"></a>00161                 {
<a name="l00162"></a>00162                 <span class="keywordtype">int</span> imageIndex = ir_x + ir_y * imageStep;
<a name="l00163"></a>00163                 <span class="keywordtype">float</span>   dx = imagePtr[imageIndex +1] - imagePtr[imageIndex-1],
<a name="l00164"></a>00164                         dy = imagePtr[imageIndex + imageStep] - imagePtr[imageIndex - imageStep];
<a name="l00165"></a>00165 
<a name="l00166"></a>00166                 dXX += dx*dx;
<a name="l00167"></a>00167                 dYY += dy*dy;
<a name="l00168"></a>00168                 dXY += dx*dy;
<a name="l00169"></a>00169                 }
<a name="l00170"></a>00170 
<a name="l00171"></a>00171         <span class="keywordtype">int</span> nPixels = 2.0 * POW2(2*nHalfBoxSize+1);
<a name="l00172"></a>00172         dXX = dXX / nPixels;
<a name="l00173"></a>00173         dYY = dYY / nPixels;
<a name="l00174"></a>00174         dXY = dXY / nPixels;
<a name="l00175"></a>00175           
<a name="l00176"></a>00176         <span class="comment">// Find and return smaller eigenvalue:</span>
<a name="l00177"></a>00177         <span class="keywordflow">return</span> 0.5 * (dXX + dYY - sqrt( (dXX + dYY) * (dXX + dYY) - 4.0 * (dXX * dYY - dXY * dXY) ));
<a name="l00178"></a>00178         };
<a name="l00179"></a>00179 
<a name="l00180"></a>00180 QMap&lt;double, QPointF&gt; pointsByShiTomasiValue(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> &amp; image, <span class="keyword">const</span> QList&lt;QPointF&gt; &amp;points, <span class="keyword">const</span> <span class="keywordtype">int</span> shiTomasiRadius)
<a name="l00181"></a>00181         {
<a name="l00182"></a>00182         <span class="keyword">const</span> <span class="keywordtype">int</span>       imgCols = image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(),
<a name="l00183"></a>00183                         imgRows = image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>(),
<a name="l00184"></a>00184                         maxCol = imgCols - shiTomasiRadius -1,
<a name="l00185"></a>00185                         maxRows = imgRows - shiTomasiRadius - 1;
<a name="l00186"></a>00186 
<a name="l00187"></a>00187         <span class="keyword">const</span> <span class="keywordtype">int</span> imageStep = image.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>();
<a name="l00188"></a>00188         <span class="keyword">const</span> uChar *imagePtr = image.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>();
<a name="l00189"></a>00189 
<a name="l00190"></a>00190         <span class="comment">// Insert corners in the map, sorted by their Shi-Tomasi score.</span>
<a name="l00191"></a>00191         QMap&lt;double, QPointF&gt; pointsMap;
<a name="l00192"></a>00192         <span class="keywordflow">foreach</span>(QPointF point, points)
<a name="l00193"></a>00193                 {
<a name="l00194"></a>00194                 <span class="keyword">const</span> <span class="keywordtype">double</span> x = point.x(), y = point.y();
<a name="l00195"></a>00195                 <span class="keywordflow">if</span> ( x &gt; shiTomasiRadius and x &lt; maxCol and y &gt; shiTomasiRadius and y &lt; maxRows)
<a name="l00196"></a>00196                         pointsMap.insertMulti( -ShiTomasiScore(imagePtr, imageStep, x, y, shiTomasiRadius), point);
<a name="l00197"></a>00197                 }
<a name="l00198"></a>00198         <span class="keywordflow">return</span> pointsMap;
<a name="l00199"></a>00199         }
<a name="l00200"></a>00200 
<a name="l00201"></a>00201 <span class="preprocessor">#ifdef QVIPP</span>
<a name="l00202"></a>00202 <span class="preprocessor"></span>QList&lt;QPointF&gt; hiPassPointDetector(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> &amp;image, <span class="keyword">const</span> <span class="keywordtype">int</span> threshold)
<a name="l00203"></a>00203         {
<a name="l00204"></a>00204         <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> gauss3x3;
<a name="l00205"></a>00205         <a class="code" href="group__qvippFF.html#gae5c1010fcf026e45590b363519769da5" title="QVision wrapper function for IPP&amp;#39;s ippiFilterGauss_8u_C1R.">FilterGauss</a>(image, gauss3x3, ippMskSize3x3, image.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().topLeft() + QPoint(1,1));
<a name="l00206"></a>00206 
<a name="l00207"></a>00207         <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> hiPass;
<a name="l00208"></a>00208         <a class="code" href="group__qvippFF.html#ga103146095de7a376dfb779a63e6a0f6a" title="QVision wrapper function for IPP&amp;#39;s ippiFilterHipass_8u_C1R.">FilterHipass</a>(gauss3x3, hiPass, ippMskSize3x3, gauss3x3.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().topLeft() + QPoint(1,1));
<a name="l00209"></a>00209 
<a name="l00210"></a>00210         <span class="keywordflow">return</span> getLocalExtremaPixels(hiPass, threshold);
<a name="l00211"></a>00211         }
<a name="l00212"></a>00212 
<a name="l00213"></a>00213 QList&lt;QPointF&gt; DoGPointDetector(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> &amp;image, <span class="keyword">const</span> <span class="keywordtype">int</span> threshold)
<a name="l00214"></a>00214         {
<a name="l00215"></a>00215         <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> gauss3x3;
<a name="l00216"></a>00216         <a class="code" href="group__qvippFF.html#gae5c1010fcf026e45590b363519769da5" title="QVision wrapper function for IPP&amp;#39;s ippiFilterGauss_8u_C1R.">FilterGauss</a>(image, gauss3x3, ippMskSize3x3, image.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().topLeft() + QPoint(1,1));
<a name="l00217"></a>00217 
<a name="l00218"></a>00218         <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> gauss5x5;
<a name="l00219"></a>00219         <a class="code" href="group__qvippFF.html#gae5c1010fcf026e45590b363519769da5" title="QVision wrapper function for IPP&amp;#39;s ippiFilterGauss_8u_C1R.">FilterGauss</a>(gauss3x3, gauss5x5, ippMskSize3x3, gauss3x3.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().topLeft() + QPoint(1,1));
<a name="l00220"></a>00220 
<a name="l00221"></a>00221         gauss3x3.<a class="code" href="classQVGenericImage.html#a2e01c2584cee10559bf1aac1ca7e287b" title="Set the region of interest of the image.">setROI</a>(gauss5x5.getROI());
<a name="l00222"></a>00222 
<a name="l00223"></a>00223         <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> absDiff;
<a name="l00224"></a>00224         <a class="code" href="group__qvippIAALO.html#ga3590c52ad9bdc161f350b49277b13a65" title="Calculate absolute difference between corresponding pixels of the two images or between...">AbsDiff</a>(gauss3x3, gauss5x5, absDiff, gauss5x5.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().topLeft());
<a name="l00225"></a>00225 
<a name="l00226"></a>00226         <span class="keywordflow">return</span> getLocalExtremaPixels(absDiff, threshold);
<a name="l00227"></a>00227         }
<a name="l00228"></a>00228 
<a name="l00229"></a>00229 <span class="comment">/*QList&lt;QPointF&gt; hiPassPointDetector(const QVImage&lt;uChar, 1&gt; &amp;image, const int threshold)</span>
<a name="l00230"></a>00230 <span class="comment">        {</span>
<a name="l00231"></a>00231 <span class="comment">        QVImage&lt;uChar, 1&gt; gauss3x3;</span>
<a name="l00232"></a>00232 <span class="comment">        FilterGauss(image, gauss3x3, ippMskSize3x3, QPoint(1,1));</span>
<a name="l00233"></a>00233 <span class="comment"></span>
<a name="l00234"></a>00234 <span class="comment">        QVImage&lt;uChar, 1&gt; hiPass;</span>
<a name="l00235"></a>00235 <span class="comment">        FilterHipass(gauss3x3, hiPass, ippMskSize3x3, QPoint(1,1));</span>
<a name="l00236"></a>00236 <span class="comment"></span>
<a name="l00237"></a>00237 <span class="comment">        return getLocalExtremaPixels(hiPass, threshold);</span>
<a name="l00238"></a>00238 <span class="comment">        }</span>
<a name="l00239"></a>00239 <span class="comment"></span>
<a name="l00240"></a>00240 <span class="comment">QList&lt;QPointF&gt; DoGPointDetector(const QVImage&lt;uChar, 1&gt; &amp;image, const int threshold)</span>
<a name="l00241"></a>00241 <span class="comment">        {</span>
<a name="l00242"></a>00242 <span class="comment">        QVImage&lt;uChar, 1&gt; gauss3x3;</span>
<a name="l00243"></a>00243 <span class="comment">        FilterGauss(image, gauss3x3, ippMskSize3x3, QPoint(1,1));</span>
<a name="l00244"></a>00244 <span class="comment"></span>
<a name="l00245"></a>00245 <span class="comment">        QVImage&lt;uChar, 1&gt; gauss5x5;</span>
<a name="l00246"></a>00246 <span class="comment">        FilterGauss(gauss3x3, gauss5x5, ippMskSize3x3, QPoint(1,1));</span>
<a name="l00247"></a>00247 <span class="comment"></span>
<a name="l00248"></a>00248 <span class="comment">        gauss3x3.setROI(gauss5x5.getROI());</span>
<a name="l00249"></a>00249 <span class="comment"></span>
<a name="l00250"></a>00250 <span class="comment">        QVImage&lt;uChar, 1&gt; absDiff;</span>
<a name="l00251"></a>00251 <span class="comment">        AbsDiff(gauss3x3, gauss5x5, absDiff);</span>
<a name="l00252"></a>00252 <span class="comment">        return getLocalExtremaPixels(absDiff, threshold);</span>
<a name="l00253"></a>00253 <span class="comment">        }*/</span>
<a name="l00254"></a>00254 
<a name="l00255"></a><a class="code" href="group__qvipp.html#ga500350a4e3dc3d05b99bd034ab65a67b">00255</a> <span class="keywordtype">void</span> <a class="code" href="group__qvipp.html#ga500350a4e3dc3d05b99bd034ab65a67b" title="Obtains the Harris corner response image.">FilterHarrisCornerResponseImage</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> &amp;result, <span class="keywordtype">int</span> aperture, <span class="keywordtype">int</span> avgwindow, <span class="keyword">const</span> QPoint &amp;<span class="comment">/*destROIOffset*/</span>)
<a name="l00256"></a>00256         {
<a name="l00257"></a>00257         <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> buffer;
<a name="l00258"></a>00258         <a class="code" href="group__qvippCV.html#ga4a7017e5e9b0df7161ffc48285f3d920" title="Allocates size in a buffer image for temporary data for function MinEigenValGet.This...">MinEigenValGetBufferSize</a>(image, buffer);
<a name="l00259"></a>00259 
<a name="l00260"></a>00260         <a class="code" href="group__qvippCV.html#gab2eadd7360e07f47881c2727bf28b2df" title="Calculates the minimal eigen value of image blocks for corner detection.This function...">MinEigenVal</a>(image, result, ippKernelSobel, aperture, avgwindow, buffer);
<a name="l00261"></a>00261         }
<a name="l00262"></a>00262 
<a name="l00263"></a><a class="code" href="group__qvipp.html#ga26877fdb37dbf494fa5672d84b7d3519">00263</a> <span class="keywordtype">void</span> <a class="code" href="group__qvipp.html#ga26877fdb37dbf494fa5672d84b7d3519" title="Obtains the DoG corner response image.">FilterDoG</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;result)
<a name="l00264"></a>00264         {
<a name="l00265"></a>00265         <span class="keyword">const</span> uInt rows = image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>(), cols = image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>();
<a name="l00266"></a>00266         <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> gauss3x3(cols, rows), gauss5x5(cols, rows);
<a name="l00267"></a>00267         
<a name="l00268"></a>00268         <span class="comment">// ¿TODO: llevar a mismo marco común?</span>
<a name="l00269"></a>00269         <a class="code" href="group__qvippFF.html#gae5c1010fcf026e45590b363519769da5" title="QVision wrapper function for IPP&amp;#39;s ippiFilterGauss_8u_C1R.">FilterGauss</a>(image, gauss3x3, ippMskSize3x3, QPoint(1,1));
<a name="l00270"></a>00270         <a class="code" href="group__qvippFF.html#gae5c1010fcf026e45590b363519769da5" title="QVision wrapper function for IPP&amp;#39;s ippiFilterGauss_8u_C1R.">FilterGauss</a>(image, gauss5x5, ippMskSize5x5, QPoint(2,2));
<a name="l00271"></a>00271 
<a name="l00272"></a>00272         gauss3x3.<a class="code" href="classQVGenericImage.html#a2e01c2584cee10559bf1aac1ca7e287b" title="Set the region of interest of the image.">setROI</a>(gauss5x5.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>());
<a name="l00273"></a>00273 
<a name="l00274"></a>00274         <a class="code" href="group__qvippIAALO.html#ga3590c52ad9bdc161f350b49277b13a65" title="Calculate absolute difference between corresponding pixels of the two images or between...">AbsDiff</a>(gauss3x3, gauss5x5, result);    
<a name="l00275"></a>00275         }
<a name="l00276"></a>00276 
<a name="l00277"></a><a class="code" href="group__qvipp.html#gaa9474c9f380746aaa24f9997bada59f5">00277</a> <span class="keywordtype">void</span> <a class="code" href="group__qvipp.html#gaa9474c9f380746aaa24f9997bada59f5" title="Obtains the Sobel corner response image.">SobelCornerResponseImage</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> &amp;image, <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> &amp;result)
<a name="l00278"></a>00278         {
<a name="l00279"></a>00279         std::cerr &lt;&lt; <span class="stringliteral">&quot;WARNING: SobelCornerResponseImage is deprecated. Use FilterHessianCornerResponseImage instead.&quot;</span> &lt;&lt; std::endl;
<a name="l00280"></a>00280         <a class="code" href="group__qvipp.html#ga5e1dd92e6da496d1e621861eb2b67cf9" title="Obtains the Hessian corner response image.">FilterHessianCornerResponseImage</a>(image, result);
<a name="l00281"></a>00281         }
<a name="l00282"></a>00282 
<a name="l00283"></a><a class="code" href="group__qvipp.html#ga5e1dd92e6da496d1e621861eb2b67cf9">00283</a> <span class="keywordtype">void</span> <a class="code" href="group__qvipp.html#ga5e1dd92e6da496d1e621861eb2b67cf9" title="Obtains the Hessian corner response image.">FilterHessianCornerResponseImage</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> &amp;image, <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> &amp;result, <span class="keyword">const</span> QPoint &amp;destROIOffset)
<a name="l00284"></a>00284         {
<a name="l00285"></a>00285         <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> Gx, Gy, Gxx, Gxy, Gyy, GxyGxy, GxxGyy;
<a name="l00286"></a>00286 
<a name="l00287"></a>00287         <a class="code" href="group__qvippFF.html#ga80cdf87494c982146fbaf42fa4e1886f" title="QVision wrapper function for IPP&amp;#39;s ippiFilterSobelHorizMask_32f_C1R.">FilterSobelHorizMask</a>(image,Gx, ippMskSize3x3);
<a name="l00288"></a>00288         <a class="code" href="group__qvippFF.html#gac4c214ba6435857ee9874d2103e99418" title="QVision wrapper function for IPP&amp;#39;s ippiFilterSobelVertMask_32f_C1R.">FilterSobelVertMask</a>(image,Gy, ippMskSize3x3);
<a name="l00289"></a>00289 
<a name="l00290"></a>00290         <a class="code" href="group__qvippFF.html#ga80cdf87494c982146fbaf42fa4e1886f" title="QVision wrapper function for IPP&amp;#39;s ippiFilterSobelHorizMask_32f_C1R.">FilterSobelHorizMask</a>(Gx,Gxx, ippMskSize3x3, QPoint(2,2));
<a name="l00291"></a>00291         <a class="code" href="group__qvippFF.html#gac4c214ba6435857ee9874d2103e99418" title="QVision wrapper function for IPP&amp;#39;s ippiFilterSobelVertMask_32f_C1R.">FilterSobelVertMask</a>(Gy,Gyy, ippMskSize3x3, QPoint(2,2));
<a name="l00292"></a>00292         <a class="code" href="group__qvippFF.html#gac4c214ba6435857ee9874d2103e99418" title="QVision wrapper function for IPP&amp;#39;s ippiFilterSobelVertMask_32f_C1R.">FilterSobelVertMask</a>(Gx,Gxy, ippMskSize3x3, QPoint(2,2));
<a name="l00293"></a>00293 
<a name="l00294"></a>00294         Gxx.<a class="code" href="classQVGenericImage.html#a2e01c2584cee10559bf1aac1ca7e287b" title="Set the region of interest of the image.">setROI</a>(Gxy.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>());
<a name="l00295"></a>00295         Gyy.<a class="code" href="classQVGenericImage.html#a2e01c2584cee10559bf1aac1ca7e287b" title="Set the region of interest of the image.">setROI</a>(Gxy.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>());
<a name="l00296"></a>00296 
<a name="l00297"></a>00297         <a class="code" href="group__qvippIAALO.html#gaf69fed782124cc0f79894de83b83e82a" title="Adds, subtracts, or multiplies pixel values of two source images and places the results...">Mul</a>(Gxy, Gxy, GxyGxy);
<a name="l00298"></a>00298         <a class="code" href="group__qvippIAALO.html#gaf69fed782124cc0f79894de83b83e82a" title="Adds, subtracts, or multiplies pixel values of two source images and places the results...">Mul</a>(Gxx, Gyy, GxxGyy);
<a name="l00299"></a>00299         <a class="code" href="group__qvippIAALO.html#ga3590c52ad9bdc161f350b49277b13a65" title="Calculate absolute difference between corresponding pixels of the two images or between...">AbsDiff</a>(GxyGxy, GxxGyy, result, destROIOffset);
<a name="l00300"></a>00300         }
<a name="l00301"></a>00301 
<a name="l00302"></a>00302 <span class="preprocessor">#ifdef GSL_AVAILABLE</span>
<a name="l00303"></a><a class="code" href="group__qvipp.html#gaacf3624cc8f531fccb9a436878af3fba">00303</a> <span class="preprocessor"></span><span class="keywordtype">void</span> <a class="code" href="group__qvipp.html#gaacf3624cc8f531fccb9a436878af3fba" title="Applies a separable filter.">FilterSeparable</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat, 1&gt;</a> &amp;image, <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat, 1&gt;</a> &amp;dest,
<a name="l00304"></a>00304         <span class="keyword">const</span> <a class="code" href="classQVVector.html" title="Implementation of numerical vectors.">QVVector</a> &amp;rowFilter, <span class="keyword">const</span> <a class="code" href="classQVVector.html" title="Implementation of numerical vectors.">QVVector</a> &amp;colFilter, <span class="keyword">const</span> QPoint &amp;destROIOffset)
<a name="l00305"></a>00305         {
<a name="l00306"></a>00306         <span class="keyword">const</span> uInt cols = image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(), rows = image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>();
<a name="l00307"></a>00307         <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> rowFiltered(cols, rows);
<a name="l00308"></a>00308         <a class="code" href="group__qvippFF.html#ga1a5d630d6aa13bd38ebd10c6cc2c243e" title="Filters an image using a spatial kernel that consists of a single row.This function...">FilterRow</a>(image, rowFiltered, rowFilter);
<a name="l00309"></a>00309         <a class="code" href="group__qvippFF.html#ga5386b7a396525c51c65fbbe60ea83c9f" title="Filters an image using a spatial kernel that consists of a single column.This function...">FilterColumn</a>(rowFiltered, dest, colFilter, destROIOffset);
<a name="l00310"></a>00310         }
<a name="l00311"></a>00311 <span class="preprocessor">#endif // GSL_AVAILABLE</span>
<a name="l00312"></a>00312 <span class="preprocessor"></span>
<a name="l00313"></a><a class="code" href="group__qvipp.html#gaa3b64cec3b1037dc5935e6c37ef277e6">00313</a> QMap&lt;sFloat, QPointF&gt;  <a class="code" href="group__qvipp.html#gaa3b64cec3b1037dc5935e6c37ef277e6" title="Finds luminance peaks in the input image.">fastMaximalPoints</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> &amp;image, <span class="keyword">const</span> <span class="keywordtype">double</span> threshold, <span class="keyword">const</span> <span class="keywordtype">int</span> windowRadius)
<a name="l00314"></a>00314         {
<a name="l00315"></a>00315         <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> maxImage;
<a name="l00316"></a>00316         <a class="code" href="group__qvippFF.html#ga30636f7f21a0c31e2be512cd81885276" title="Applies the &amp;quot;max&amp;quot; filter to an image.">FilterMax</a>(image, maxImage, QSize(2*windowRadius+1, 2*windowRadius+1), QPoint(0,0), image.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().topLeft() + QPoint(windowRadius, windowRadius));
<a name="l00317"></a>00317 
<a name="l00318"></a>00318         <span class="keyword">const</span> QRect     ROI = maxImage.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>();
<a name="l00319"></a>00319         <span class="keyword">const</span> <span class="keywordtype">int</span>       maxStep = maxImage.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>() / <span class="keyword">sizeof</span>(sFloat),
<a name="l00320"></a>00320                         imageStep = image.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>() / <span class="keyword">sizeof</span>(sFloat);
<a name="l00321"></a>00321 
<a name="l00322"></a>00322         QMap&lt;sFloat, QPointF&gt; sortedPoints;
<a name="l00323"></a>00323 
<a name="l00324"></a>00324         sFloat *actualPtr = (sFloat *) image.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>() + (imageStep + 1) * windowRadius;
<a name="l00325"></a>00325         sFloat *maxPtr = (sFloat *) maxImage.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>() + (maxStep + 1) * windowRadius;
<a name="l00326"></a>00326 
<a name="l00327"></a>00327         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j = 0; j &lt; ROI.height(); j++, actualPtr += imageStep, maxPtr += maxStep)
<a name="l00328"></a>00328                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = 0; i &lt; ROI.width(); i++)
<a name="l00329"></a>00329                         <span class="keywordflow">if</span> ( (actualPtr[i] &gt;= threshold) and (maxPtr[i] == actualPtr[i]) )
<a name="l00330"></a>00330                                 sortedPoints.insertMulti(-actualPtr[i], QPointF(i+ROI.x(), j+ROI.y())); 
<a name="l00331"></a>00331 
<a name="l00332"></a>00332         <span class="keywordflow">return</span> sortedPoints;
<a name="l00333"></a>00333         }
<a name="l00334"></a>00334 
<a name="l00335"></a><a class="code" href="group__qvipp.html#gacbdf9bb3ccccd60cf561cf7fbd5b94c7">00335</a> QMap&lt;uChar, QPointF&gt;  <a class="code" href="group__qvipp.html#gaa3b64cec3b1037dc5935e6c37ef277e6" title="Finds luminance peaks in the input image.">fastMaximalPoints</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <span class="keyword">const</span> <span class="keywordtype">double</span> threshold, <span class="keyword">const</span> <span class="keywordtype">int</span> windowRadius)
<a name="l00336"></a>00336         {
<a name="l00337"></a>00337         <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> maxImage;
<a name="l00338"></a>00338         <a class="code" href="group__qvippFF.html#ga30636f7f21a0c31e2be512cd81885276" title="Applies the &amp;quot;max&amp;quot; filter to an image.">FilterMax</a>(image, maxImage, QSize(2*windowRadius+1, 2*windowRadius+1), QPoint(0,0), image.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>().topLeft() + QPoint(windowRadius, windowRadius));
<a name="l00339"></a>00339 
<a name="l00340"></a>00340         <span class="keyword">const</span> QRect     ROI = maxImage.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>();
<a name="l00341"></a>00341         <span class="keyword">const</span> <span class="keywordtype">int</span>       maxStep = maxImage.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>() / <span class="keyword">sizeof</span>(uChar),
<a name="l00342"></a>00342                                 imageStep = image.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>() / <span class="keyword">sizeof</span>(uChar);
<a name="l00343"></a>00343 
<a name="l00344"></a>00344         QMap&lt;uChar, QPointF&gt; sortedPoints;
<a name="l00345"></a>00345 
<a name="l00346"></a>00346         uChar *actualPtr = (uChar *) image.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>() + (imageStep + 1) * windowRadius;
<a name="l00347"></a>00347         uChar *maxPtr = (uChar *) maxImage.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>() + (maxStep + 1) * windowRadius;
<a name="l00348"></a>00348 
<a name="l00349"></a>00349         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j = 0; j &lt; ROI.height(); j++, actualPtr += imageStep, maxPtr += maxStep)
<a name="l00350"></a>00350                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = 0; i &lt; ROI.width(); i++)
<a name="l00351"></a>00351                         <span class="keywordflow">if</span> ( (actualPtr[i] &gt;= threshold) and (maxPtr[i] == actualPtr[i]) )
<a name="l00352"></a>00352                                 sortedPoints.insertMulti(-actualPtr[i], QPointF(i+ROI.x(), j+ROI.y())); 
<a name="l00353"></a>00353 
<a name="l00354"></a>00354         <span class="keywordflow">return</span> sortedPoints;
<a name="l00355"></a>00355         }
<a name="l00356"></a>00356 
<a name="l00357"></a>00357 <span class="preprocessor">#define DEFINE_QVDTA_FUNCTION_NORMALIZE(TYPE, C)                                                                \</span>
<a name="l00358"></a>00358 <span class="preprocessor">void FilterNormalize(const QVImage&lt;TYPE,C&gt; &amp;image, QVImage&lt;TYPE,C&gt; &amp;equalized, const QPoint &amp;destROIOffset)             \</span>
<a name="l00359"></a>00359 <span class="preprocessor">        {                                                                                                               \</span>
<a name="l00360"></a>00360 <span class="preprocessor">        TYPE    maxVal, minVal;                                         \</span>
<a name="l00361"></a>00361 <span class="preprocessor">                                                                        \</span>
<a name="l00362"></a>00362 <span class="preprocessor">        Max(image,maxVal);                                              \</span>
<a name="l00363"></a>00363 <span class="preprocessor">        Min(image,minVal);                                              \</span>
<a name="l00364"></a>00364 <span class="preprocessor">                                                                        \</span>
<a name="l00365"></a>00365 <span class="preprocessor">        QVImage&lt;TYPE,C&gt; temp, result;                                   \</span>
<a name="l00366"></a>00366 <span class="preprocessor">        SubC(image, minVal, temp);                                      \</span>
<a name="l00367"></a>00367 <span class="preprocessor">        MulC(temp, 255/(maxVal-minVal), result, 1, destROIOffset);      \</span>
<a name="l00368"></a>00368 <span class="preprocessor">        equalized = result;                                             \</span>
<a name="l00369"></a>00369 <span class="preprocessor">        }</span>
<a name="l00370"></a>00370 <span class="preprocessor"></span>
<a name="l00371"></a>00371 DEFINE_QVDTA_FUNCTION_NORMALIZE(uChar,1);
<a name="l00372"></a>00372 
<a name="l00373"></a>00373 <span class="preprocessor">#define DEFINE_QVDTA_FUNCTION_NORMALIZE2(TYPE, C)                                                               \</span>
<a name="l00374"></a>00374 <span class="preprocessor">void FilterNormalize(const QVImage&lt;TYPE,C&gt; &amp;image, QVImage&lt;TYPE,C&gt; &amp;equalized, const QPoint &amp;destROIOffset)             \</span>
<a name="l00375"></a>00375 <span class="preprocessor">        {                                                                                                               \</span>
<a name="l00376"></a>00376 <span class="preprocessor">        uInt    rows = image.getRows(), cols = image.getCols();         \</span>
<a name="l00377"></a>00377 <span class="preprocessor">        TYPE    maxVal, minVal;                                         \</span>
<a name="l00378"></a>00378 <span class="preprocessor">                                                                        \</span>
<a name="l00379"></a>00379 <span class="preprocessor">        Max(image,maxVal);                                              \</span>
<a name="l00380"></a>00380 <span class="preprocessor">        Min(image,minVal);                                              \</span>
<a name="l00381"></a>00381 <span class="preprocessor">                                                                        \</span>
<a name="l00382"></a>00382 <span class="preprocessor">        QVImage&lt;TYPE,C&gt; temp(cols, rows), result(cols, rows);           \</span>
<a name="l00383"></a>00383 <span class="preprocessor">        SubC(image, minVal, temp);                                      \</span>
<a name="l00384"></a>00384 <span class="preprocessor">        MulC(temp, 255/(maxVal-minVal), result, destROIOffset);         \</span>
<a name="l00385"></a>00385 <span class="preprocessor">        equalized = result;                                             \</span>
<a name="l00386"></a>00386 <span class="preprocessor">        }</span>
<a name="l00387"></a>00387 <span class="preprocessor"></span>DEFINE_QVDTA_FUNCTION_NORMALIZE2(sFloat,1);
<a name="l00388"></a>00388 <span class="preprocessor">#endif // IPP_AVAILABLE</span>
<a name="l00389"></a>00389 <span class="preprocessor"></span>
<a name="l00390"></a><a class="code" href="group__qvip.html#gade8ced9dc785b2238de521daff597b13">00390</a> <span class="keywordtype">void</span> <a class="code" href="group__qvip.html#gade8ced9dc785b2238de521daff597b13" title="Generates a binary image of local grey-scale maximal value pixels.This function receives...">FilterLocalMax</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> &amp;src, <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;dest, uInt colMaskSize, uInt rowMaskSize, sFloat threshold)
<a name="l00391"></a>00391         {
<a name="l00392"></a>00392         <span class="keyword">const</span> <span class="keywordtype">int</span> cols = src.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(), rows = src.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>();
<a name="l00393"></a>00393         <a class="code" href="group__qvippIDEAIF.html#gae2bed87200a1f753701bf5fc1e7a476b" title="Sets pixels in the image buffer to a constant value.">Set</a>(0, dest);
<a name="l00394"></a>00394         sFloat actual;
<a name="l00395"></a>00395         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(sFloat,src);
<a name="l00396"></a>00396         <a class="code" href="group__qvip.html#ga42904f931068a3ea3f6bdb90861d1dc1" title="Initializes image to be written or read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_WRITE</a>(uChar,dest);
<a name="l00397"></a>00397         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> row = ((<span class="keywordtype">int</span>)rowMaskSize); row &lt; rows-((int)rowMaskSize); row++)
<a name="l00398"></a>00398                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> col = ((<span class="keywordtype">int</span>)colMaskSize); col &lt; cols-((int)colMaskSize); col++)
<a name="l00399"></a>00399                         {
<a name="l00400"></a>00400                         actual = <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(src, col, row,0);
<a name="l00401"></a>00401                         <span class="keywordflow">if</span> (actual &gt;= threshold)
<a name="l00402"></a>00402                                 {
<a name="l00403"></a>00403                                 <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(dest, col, row, 0) = std::numeric_limits&lt;unsigned char&gt;::max();
<a name="l00404"></a>00404                                 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> j = ((<span class="keywordtype">int</span>)row-rowMaskSize); (j &lt; row+((int)rowMaskSize)) &amp;&amp; (QVIMAGE_PIXEL(dest, col, row, 0) &gt; 0); j++)
<a name="l00405"></a>00405                                         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = ((<span class="keywordtype">int</span>)col-colMaskSize); i &lt; col+((int)colMaskSize); i++)
<a name="l00406"></a>00406                                                 <span class="keywordflow">if</span> ( ((i != col) || (j != row)) &amp;&amp; (actual &lt;= <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(src, i, j, 0)) )
<a name="l00407"></a>00407                                                         {
<a name="l00408"></a>00408                                                         <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(dest, col, row, 0) = 0;
<a name="l00409"></a>00409                                                         <span class="keywordflow">break</span>;
<a name="l00410"></a>00410                                                         }
<a name="l00411"></a>00411                                 }
<a name="l00412"></a>00412                         }
<a name="l00413"></a>00413         }
<a name="l00414"></a>00414 
<a name="l00416"></a><a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">00416</a> <span class="keywordtype">int</span> <a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">myFloodFill</a>(<a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, uInt x, uInt y, uInt value, uInt minVal, uInt maxVal)
<a name="l00417"></a>00417         {
<a name="l00418"></a>00418         <span class="comment">// Value should be inside range [minVal, maxVal]</span>
<a name="l00419"></a>00419         Q_ASSERT( (value &lt;= minVal) || (value &gt;= maxVal) );
<a name="l00420"></a>00420         Q_ASSERT( minVal &lt;= maxVal );
<a name="l00421"></a>00421 
<a name="l00422"></a>00422         <span class="comment">// Coordinates should be inside the image.</span>
<a name="l00423"></a>00423         <span class="keywordflow">if</span> ( (x &gt;= image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>()) || (y &gt;= image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>()))
<a name="l00424"></a>00424                 <span class="keywordflow">return</span> 0;
<a name="l00425"></a>00425 
<a name="l00426"></a>00426         <span class="keywordflow">if</span> ( (image(x,y) &lt; minVal) || (image(x,y) &gt; maxVal) )
<a name="l00427"></a>00427                 <span class="keywordflow">return</span> 0;
<a name="l00428"></a>00428 
<a name="l00429"></a>00429         image(x,y) = value;
<a name="l00430"></a>00430 
<a name="l00431"></a>00431         <span class="keywordtype">int</span> val = 1;
<a name="l00432"></a>00432         val += <a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">myFloodFill</a>(image, x-1, y, value, minVal, maxVal);
<a name="l00433"></a>00433         val += <a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">myFloodFill</a>(image, x, y-1, value, minVal, maxVal);
<a name="l00434"></a>00434         val += <a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">myFloodFill</a>(image, x+1, y, value, minVal, maxVal);
<a name="l00435"></a>00435         val += <a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">myFloodFill</a>(image, x, y+1, value, minVal, maxVal);
<a name="l00436"></a>00436 
<a name="l00437"></a>00437         val += <a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">myFloodFill</a>(image, x-1, y-1, value, minVal, maxVal);
<a name="l00438"></a>00438         val += <a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">myFloodFill</a>(image, x-1, y+1, value, minVal, maxVal);
<a name="l00439"></a>00439         val += <a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">myFloodFill</a>(image, x+1, y-1, value, minVal, maxVal);
<a name="l00440"></a>00440         val += <a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">myFloodFill</a>(image, x+1, y+1, value, minVal, maxVal);
<a name="l00441"></a>00441 
<a name="l00442"></a>00442         <span class="keywordflow">return</span> val;
<a name="l00443"></a>00443         }
<a name="l00444"></a>00444 
<a name="l00446"></a>00446 
<a name="l00447"></a>00447 <span class="preprocessor">#include &lt;QVComponentTree&gt;</span>
<a name="l00448"></a>00448 
<a name="l00449"></a>00449 <span class="keywordtype">void</span> pruneLowComponentTreeAux(<a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <a class="code" href="classQVComponentTree.html" title="Image component tree data structure.">QVComponentTree</a> &amp;componentTree, uInt minArea, uInt node, uInt validThreshold)
<a name="l00450"></a>00450         {
<a name="l00451"></a>00451         Q_ASSERT(componentTree.<a class="code" href="classQVComponentTree.html#a270428438cc9b604e9261cf3c741c217" title="Returns the accumulative histogram of the gray-level values of the pixels, for a...">area</a>(node)[componentTree.<a class="code" href="classQVComponentTree.html#af6f964ef20bf880f7aab393ec829e575" title="Returns gray-scale value of the points at the vertex of a node.">firstThreshold</a>(node)] != 0);
<a name="l00452"></a>00452         Q_ASSERT(componentTree.<a class="code" href="classQVComponentTree.html#a270428438cc9b604e9261cf3c741c217" title="Returns the accumulative histogram of the gray-level values of the pixels, for a...">area</a>(node)[componentTree.<a class="code" href="classQVComponentTree.html#ae1f6def9a17a983f3d2047eb564cc3ad" title="Returns gray-scale value of the points at the base of a node.">lastThreshold</a>(node)] != 0);
<a name="l00453"></a>00453         Q_ASSERT(validThreshold &gt;= componentTree.<a class="code" href="classQVComponentTree.html#ae1f6def9a17a983f3d2047eb564cc3ad" title="Returns gray-scale value of the points at the base of a node.">lastThreshold</a>(node));
<a name="l00454"></a>00454 
<a name="l00455"></a>00455         <span class="keywordtype">bool</span> prune = <span class="keyword">false</span>;
<a name="l00456"></a>00456         <span class="keywordtype">int</span> lastValidThreshold = validThreshold;
<a name="l00457"></a>00457 
<a name="l00458"></a>00458         <span class="comment">// Here we decide if this node should be directly pruned</span>
<a name="l00459"></a>00459         <span class="comment">// or if there&#39;s any sub-node we should prune</span>
<a name="l00460"></a>00460         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> threshold = componentTree.<a class="code" href="classQVComponentTree.html#ae1f6def9a17a983f3d2047eb564cc3ad" title="Returns gray-scale value of the points at the base of a node.">lastThreshold</a>(node); threshold &gt;= componentTree.<a class="code" href="classQVComponentTree.html#af6f964ef20bf880f7aab393ec829e575" title="Returns gray-scale value of the points at the vertex of a node.">firstThreshold</a>(node) &amp;&amp; !prune; threshold--)
<a name="l00461"></a>00461                 <span class="keywordflow">if</span> (componentTree.<a class="code" href="classQVComponentTree.html#a270428438cc9b604e9261cf3c741c217" title="Returns the accumulative histogram of the gray-level values of the pixels, for a...">area</a>(node)[threshold] &gt; 0)
<a name="l00462"></a>00462                         {
<a name="l00463"></a>00463                         <span class="keywordflow">if</span> (componentTree.<a class="code" href="classQVComponentTree.html#a270428438cc9b604e9261cf3c741c217" title="Returns the accumulative histogram of the gray-level values of the pixels, for a...">area</a>(node)[threshold] &lt; minArea)
<a name="l00464"></a>00464                                 prune = <span class="keyword">true</span>;
<a name="l00465"></a>00465                         <span class="keywordflow">else</span>
<a name="l00466"></a>00466                                 lastValidThreshold = threshold;
<a name="l00467"></a>00467                         }
<a name="l00468"></a>00468 
<a name="l00469"></a>00469         <span class="comment">// We prune node, or get on with it&#39;s childrens</span>
<a name="l00470"></a>00470         <span class="keywordflow">if</span> (prune)
<a name="l00471"></a>00471                 <a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">myFloodFill</a>(image, componentTree.<a class="code" href="classQVComponentTree.html#a045219975a0145022d98c7fcf47642cb" title="Returns horizontal coordinate for the seed point of a node, given it&amp;#39;s index...">seedX</a>(node), componentTree.<a class="code" href="classQVComponentTree.html#ac763fa3f3de4beab5bdb072921965862" title="Returns vertical coordinate for the seed point of a node, given it&amp;#39;s index.">seedY</a>(node), lastValidThreshold, 0, lastValidThreshold-1);
<a name="l00472"></a>00472         <span class="keywordflow">else</span>
<a name="l00473"></a>00473                 <span class="keywordflow">for</span> (uInt child = componentTree.<a class="code" href="classQVComponentTree.html#a6fd2408b5112230e515623c7084601ea" title="Returns the index for the first of the childs of a node.">firstChild</a>(node); child != NULL_NODE; child = componentTree.<a class="code" href="classQVComponentTree.html#a44625404b168bb90229d611d32a628e4" title="Returns the index for the next node in the list of childs, for a node.">nextSibling</a>(child))
<a name="l00474"></a>00474                         pruneLowComponentTreeAux(image, componentTree, minArea, child, lastValidThreshold);
<a name="l00475"></a>00475         }
<a name="l00476"></a>00476 
<a name="l00477"></a>00477 <span class="keywordtype">void</span> pruneHighComponentTreeAux(<a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <a class="code" href="classQVComponentTree.html" title="Image component tree data structure.">QVComponentTree</a> &amp;componentTree, uInt minArea, uInt node, uInt validThreshold)
<a name="l00478"></a>00478         {
<a name="l00479"></a>00479         Q_ASSERT(componentTree.<a class="code" href="classQVComponentTree.html#a270428438cc9b604e9261cf3c741c217" title="Returns the accumulative histogram of the gray-level values of the pixels, for a...">area</a>(node)[componentTree.<a class="code" href="classQVComponentTree.html#af6f964ef20bf880f7aab393ec829e575" title="Returns gray-scale value of the points at the vertex of a node.">firstThreshold</a>(node)] != 0);
<a name="l00480"></a>00480         Q_ASSERT(componentTree.<a class="code" href="classQVComponentTree.html#a270428438cc9b604e9261cf3c741c217" title="Returns the accumulative histogram of the gray-level values of the pixels, for a...">area</a>(node)[componentTree.<a class="code" href="classQVComponentTree.html#ae1f6def9a17a983f3d2047eb564cc3ad" title="Returns gray-scale value of the points at the base of a node.">lastThreshold</a>(node)] != 0);
<a name="l00481"></a>00481         Q_ASSERT(validThreshold &gt;= componentTree.<a class="code" href="classQVComponentTree.html#ae1f6def9a17a983f3d2047eb564cc3ad" title="Returns gray-scale value of the points at the base of a node.">lastThreshold</a>(node));
<a name="l00482"></a>00482 
<a name="l00483"></a>00483         <span class="keywordtype">bool</span> prune = <span class="keyword">false</span>;
<a name="l00484"></a>00484         <span class="keywordtype">int</span> lastValidThreshold = validThreshold;
<a name="l00485"></a>00485 
<a name="l00486"></a>00486         <span class="comment">// Here we decide if this node should be directly pruned</span>
<a name="l00487"></a>00487         <span class="comment">// or if there&#39;s any sub-node we should prune</span>
<a name="l00488"></a>00488         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> threshold = componentTree.<a class="code" href="classQVComponentTree.html#ae1f6def9a17a983f3d2047eb564cc3ad" title="Returns gray-scale value of the points at the base of a node.">lastThreshold</a>(node); threshold &gt;= componentTree.<a class="code" href="classQVComponentTree.html#af6f964ef20bf880f7aab393ec829e575" title="Returns gray-scale value of the points at the vertex of a node.">firstThreshold</a>(node) &amp;&amp; !prune; threshold--)
<a name="l00489"></a>00489                 <span class="keywordflow">if</span> (componentTree.<a class="code" href="classQVComponentTree.html#a270428438cc9b604e9261cf3c741c217" title="Returns the accumulative histogram of the gray-level values of the pixels, for a...">area</a>(node)[threshold] &gt; 0)
<a name="l00490"></a>00490                         {
<a name="l00491"></a>00491                         <span class="keywordflow">if</span> (componentTree.<a class="code" href="classQVComponentTree.html#a270428438cc9b604e9261cf3c741c217" title="Returns the accumulative histogram of the gray-level values of the pixels, for a...">area</a>(node)[threshold] &lt; minArea)
<a name="l00492"></a>00492                                 prune = <span class="keyword">true</span>;
<a name="l00493"></a>00493                         <span class="keywordflow">else</span>
<a name="l00494"></a>00494                                 lastValidThreshold = threshold;
<a name="l00495"></a>00495                         }
<a name="l00496"></a>00496 
<a name="l00497"></a>00497         <span class="comment">// We prune node, or get on with it&#39;s childrens</span>
<a name="l00498"></a>00498         <span class="keywordflow">if</span> (prune)
<a name="l00499"></a>00499                 <a class="code" href="qvip_8cpp.html#ad59b48c43b863530b8ef45a61ef250e7">myFloodFill</a>(image, componentTree.<a class="code" href="classQVComponentTree.html#a045219975a0145022d98c7fcf47642cb" title="Returns horizontal coordinate for the seed point of a node, given it&amp;#39;s index...">seedX</a>(node), componentTree.<a class="code" href="classQVComponentTree.html#ac763fa3f3de4beab5bdb072921965862" title="Returns vertical coordinate for the seed point of a node, given it&amp;#39;s index.">seedY</a>(node), 255-lastValidThreshold, 255-lastValidThreshold+1, 255-0);
<a name="l00500"></a>00500         <span class="keywordflow">else</span>
<a name="l00501"></a>00501                 <span class="keywordflow">for</span> (uInt child = componentTree.<a class="code" href="classQVComponentTree.html#a6fd2408b5112230e515623c7084601ea" title="Returns the index for the first of the childs of a node.">firstChild</a>(node); child != NULL_NODE; child = componentTree.<a class="code" href="classQVComponentTree.html#a44625404b168bb90229d611d32a628e4" title="Returns the index for the next node in the list of childs, for a node.">nextSibling</a>(child))
<a name="l00502"></a>00502                         pruneHighComponentTreeAux(image, componentTree, minArea, child, lastValidThreshold);
<a name="l00503"></a>00503         }
<a name="l00504"></a>00504 
<a name="l00505"></a>00505 <span class="keywordtype">void</span> FilterPruneComponentTreeSmallRegions(<a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <a class="code" href="classQVComponentTree.html" title="Image component tree data structure.">QVComponentTree</a> &amp;componentTree, uInt minArea)
<a name="l00506"></a>00506         {
<a name="l00507"></a>00507         qDebug() &lt;&lt; <span class="stringliteral">&quot;pruneRegions()&quot;</span>;
<a name="l00508"></a>00508         <span class="keywordflow">if</span> (componentTree.<a class="code" href="classQVComponentTree.html#a2a94333317eb67e9d74e71fca6fc19b0" title="Returns whether this tree is inverted or not.">isInverseTree</a>())
<a name="l00509"></a>00509                 {
<a name="l00510"></a>00510                 <span class="keywordflow">if</span>(componentTree.<a class="code" href="classQVComponentTree.html#a270428438cc9b604e9261cf3c741c217" title="Returns the accumulative histogram of the gray-level values of the pixels, for a...">area</a>(componentTree.<a class="code" href="classQVComponentTree.html#a608bd4b04af5ad582c863c7dc225ad0d" title="Returns index for the root node in the image.">rootNode</a>())[componentTree.<a class="code" href="classQVComponentTree.html#ae1f6def9a17a983f3d2047eb564cc3ad" title="Returns gray-scale value of the points at the base of a node.">lastThreshold</a>(componentTree.<a class="code" href="classQVComponentTree.html#a608bd4b04af5ad582c863c7dc225ad0d" title="Returns index for the root node in the image.">rootNode</a>())] &gt; minArea)
<a name="l00511"></a>00511                         pruneHighComponentTreeAux(image, componentTree, minArea, componentTree.<a class="code" href="classQVComponentTree.html#a608bd4b04af5ad582c863c7dc225ad0d" title="Returns index for the root node in the image.">rootNode</a>(), componentTree.<a class="code" href="classQVComponentTree.html#ae1f6def9a17a983f3d2047eb564cc3ad" title="Returns gray-scale value of the points at the base of a node.">lastThreshold</a>(componentTree.<a class="code" href="classQVComponentTree.html#a608bd4b04af5ad582c863c7dc225ad0d" title="Returns index for the root node in the image.">rootNode</a>()));
<a name="l00512"></a>00512                 }
<a name="l00513"></a>00513         <span class="keywordflow">else</span>    {
<a name="l00514"></a>00514                 <span class="keywordflow">if</span>(componentTree.<a class="code" href="classQVComponentTree.html#a270428438cc9b604e9261cf3c741c217" title="Returns the accumulative histogram of the gray-level values of the pixels, for a...">area</a>(componentTree.<a class="code" href="classQVComponentTree.html#a608bd4b04af5ad582c863c7dc225ad0d" title="Returns index for the root node in the image.">rootNode</a>())[componentTree.<a class="code" href="classQVComponentTree.html#ae1f6def9a17a983f3d2047eb564cc3ad" title="Returns gray-scale value of the points at the base of a node.">lastThreshold</a>(componentTree.<a class="code" href="classQVComponentTree.html#a608bd4b04af5ad582c863c7dc225ad0d" title="Returns index for the root node in the image.">rootNode</a>())] &gt; minArea)
<a name="l00515"></a>00515                         pruneLowComponentTreeAux(image, componentTree, minArea, componentTree.<a class="code" href="classQVComponentTree.html#a608bd4b04af5ad582c863c7dc225ad0d" title="Returns index for the root node in the image.">rootNode</a>(), componentTree.<a class="code" href="classQVComponentTree.html#ae1f6def9a17a983f3d2047eb564cc3ad" title="Returns gray-scale value of the points at the base of a node.">lastThreshold</a>(componentTree.<a class="code" href="classQVComponentTree.html#a608bd4b04af5ad582c863c7dc225ad0d" title="Returns index for the root node in the image.">rootNode</a>()));
<a name="l00516"></a>00516                 }
<a name="l00517"></a>00517 
<a name="l00518"></a>00518         qDebug() &lt;&lt; <span class="stringliteral">&quot;pruneRegions() &lt;~ return&quot;</span>;
<a name="l00519"></a>00519         }
<a name="l00520"></a>00520 
<a name="l00521"></a>00521 <span class="preprocessor">#include &lt;<a class="code" href="qvdisjointset_8h.html" title="File from the QVision library.">qvmath/qvdisjointset.h</a>&gt;</span>
<a name="l00522"></a>00522 <span class="comment">//#include &lt;qvmath/qvvector.h&gt;</span>
<a name="l00523"></a>00523 
<a name="l00524"></a><a class="code" href="group__qvip.html#gad2ed4c0a62c68685797fe9c88148426a">00524</a> QMap&lt;sFloat, QPointF&gt;  <a class="code" href="group__qvip.html#gad2ed4c0a62c68685797fe9c88148426a" title="Finds luminance peaks in the input image.">maximalPoints</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;sFloat&gt;</a> &amp;cornerResponseImage, <span class="keyword">const</span> <span class="keywordtype">double</span> threshold, <span class="keyword">const</span> <span class="keywordtype">int</span> windowRadius)
<a name="l00525"></a>00525         {
<a name="l00526"></a>00526         <span class="keyword">const</span> QRect     ROI = cornerResponseImage.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>();
<a name="l00527"></a>00527         <span class="keyword">const</span> <span class="keywordtype">int</span>       step = cornerResponseImage.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>() / <span class="keyword">sizeof</span>(sFloat),
<a name="l00528"></a>00528                         windowSize = windowRadius * 2 +1;
<a name="l00529"></a>00529 
<a name="l00530"></a>00530         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(sFloat,cornerResponseImage);
<a name="l00531"></a>00531 
<a name="l00532"></a>00532         QMap&lt;sFloat, QPointF&gt; sortedPoints;
<a name="l00533"></a>00533         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> row = ROI.y() + windowRadius; row &lt; ROI.y() + ROI.height() - windowRadius; row++)
<a name="l00534"></a>00534                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> col = ROI.x() + windowRadius; col &lt; ROI.x() + ROI.width() - windowRadius; col++)
<a name="l00535"></a>00535                         {
<a name="l00536"></a>00536                         <span class="keyword">const</span> sFloat actual = <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(cornerResponseImage, col, row, 0);
<a name="l00537"></a>00537                         <span class="keywordflow">if</span> (actual &gt;= threshold)
<a name="l00538"></a>00538                                 {
<a name="l00539"></a>00539                                 <span class="keywordtype">bool</span> cond = <span class="keyword">true</span>;
<a name="l00540"></a>00540 
<a name="l00541"></a>00541                                 sFloat <span class="keyword">const</span> * pixel = &amp; <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(cornerResponseImage, col, row, 0) - windowRadius * (1 + step);
<a name="l00542"></a>00542                                 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> j = 0; j &lt; windowSize &amp;&amp; cond; j++, pixel += step - windowSize )
<a name="l00543"></a>00543                                         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; windowSize &amp;&amp; cond; i++, pixel++)
<a name="l00544"></a>00544                                                 <span class="keywordflow">if</span> ( ( i != windowRadius || j != windowRadius ) &amp;&amp; ( actual &lt;= *pixel) )
<a name="l00545"></a>00545                                                         cond = <span class="keyword">false</span>;
<a name="l00546"></a>00546 
<a name="l00547"></a>00547                                 <span class="keywordflow">if</span> (cond)
<a name="l00548"></a>00548                                         sortedPoints.insertMulti(-actual, QPointF(col+2, row+2));
<a name="l00549"></a>00549                                 }
<a name="l00550"></a>00550                         }
<a name="l00551"></a>00551 
<a name="l00552"></a>00552         <span class="keywordflow">return</span> sortedPoints;
<a name="l00553"></a>00553         }
<a name="l00554"></a>00554 
<a name="l00555"></a><a class="code" href="group__qvip.html#ga48592e8d0ecc14b8a01c373e97a0b630">00555</a> QList&lt;QPointF&gt; <a class="code" href="group__qvip.html#ga48592e8d0ecc14b8a01c373e97a0b630" title="Obtains FAST features on an image-.">FASTFeatures</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> &amp; image, <span class="keyword">const</span> <span class="keywordtype">int</span> threshold, <span class="keyword">const</span> <a class="code" href="group__qvip.html#ga2d3c88a18a68f0abe71eb8bc6fd2b277" title="FAST detection algorithms.">FASTDetectionAlgorithm</a> &amp;fastAlgorithm)
<a name="l00556"></a>00556         {
<a name="l00557"></a>00557         <span class="comment">// Convert QVImage to CVD Image</span>
<a name="l00558"></a>00558         <span class="keyword">const</span> <span class="keywordtype">int</span>       cols = image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(),
<a name="l00559"></a>00559                                 rows = image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>(),
<a name="l00560"></a>00560                                 step = image.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>();
<a name="l00561"></a>00561         <span class="keyword">const</span> byte *imgData = image.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>();
<a name="l00562"></a>00562 
<a name="l00563"></a>00563         <span class="keywordtype">int</span> num_corners;
<a name="l00564"></a>00564         xy *points;
<a name="l00565"></a>00565 
<a name="l00566"></a>00566         <span class="keywordflow">switch</span>(fastAlgorithm)
<a name="l00567"></a>00567                 {
<a name="l00568"></a>00568                 <span class="keywordflow">case</span> Fast9:
<a name="l00569"></a>00569                         points = fast9_detect_nonmax(imgData, cols, rows, step, threshold, &amp;num_corners);
<a name="l00570"></a>00570                         <span class="keywordflow">break</span>;
<a name="l00571"></a>00571                 <span class="keywordflow">case</span> Fast10:
<a name="l00572"></a>00572                         points = fast10_detect_nonmax(imgData, cols, rows, step, threshold, &amp;num_corners);
<a name="l00573"></a>00573                         <span class="keywordflow">break</span>;
<a name="l00574"></a>00574                 <span class="keywordflow">case</span> Fast11:
<a name="l00575"></a>00575                         points = fast11_detect_nonmax(imgData, cols, rows, step, threshold, &amp;num_corners);
<a name="l00576"></a>00576                         <span class="keywordflow">break</span>;
<a name="l00577"></a>00577                 <span class="keywordflow">case</span> Fast12:
<a name="l00578"></a>00578                         points = fast12_detect_nonmax(imgData, cols, rows, step, threshold, &amp;num_corners);
<a name="l00579"></a>00579                         <span class="keywordflow">break</span>;
<a name="l00580"></a>00580                 }
<a name="l00581"></a>00581 
<a name="l00582"></a>00582         QList&lt;QPointF&gt; result;
<a name="l00583"></a>00583         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_corners; i++)
<a name="l00584"></a>00584                 result &lt;&lt; QPointF(points[i].x, points[i].y);
<a name="l00585"></a>00585 
<a name="l00586"></a>00586         free(points);
<a name="l00587"></a>00587 
<a name="l00588"></a>00588         <span class="keywordflow">return</span> result;
<a name="l00589"></a>00589         }
<a name="l00590"></a>00590 
<a name="l00591"></a>00591 
<a name="l00593"></a>00593 <span class="comment">// Iterative point elimination</span>
<a name="l00594"></a>00594 <span class="preprocessor">#ifndef DOXYGEN_IGNORE_THIS</span>
<a name="l00595"></a>00595 <span class="preprocessor"></span><span class="keyword">class </span>ClassAuxIPE
<a name="l00596"></a>00596         {
<a name="l00597"></a>00597         <span class="keyword">public</span>:
<a name="l00598"></a>00598                 <span class="keywordtype">double</span> cost;
<a name="l00599"></a>00599                 <span class="keywordtype">int</span> index;
<a name="l00600"></a>00600                 ClassAuxIPE *prev,*next;
<a name="l00601"></a>00601         };
<a name="l00602"></a>00602 
<a name="l00603"></a>00603 <span class="keyword">class </span>ClassAuxIPE_F
<a name="l00604"></a>00604         {
<a name="l00605"></a>00605         <span class="keyword">public</span>:
<a name="l00606"></a>00606                 <span class="keywordtype">double</span> cost;
<a name="l00607"></a>00607                 <span class="keywordtype">int</span> index;
<a name="l00608"></a>00608                 ClassAuxIPE_F *prev,*next;
<a name="l00609"></a>00609         };
<a name="l00610"></a>00610 
<a name="l00611"></a>00611 <span class="keywordtype">bool</span> costLessThan(ClassAuxIPE* &amp;s1,ClassAuxIPE* &amp;s2)
<a name="l00612"></a>00612         {
<a name="l00613"></a>00613         <span class="keywordflow">return</span> s1-&gt;cost &lt; s2-&gt;cost;
<a name="l00614"></a>00614         }
<a name="l00615"></a>00615 
<a name="l00616"></a>00616 <span class="keywordtype">bool</span> costLessThanF(ClassAuxIPE_F* &amp;s1,ClassAuxIPE_F* &amp;s2)
<a name="l00617"></a>00617         {
<a name="l00618"></a>00618         <span class="keywordflow">return</span> s1-&gt;cost &lt; s2-&gt;cost;
<a name="l00619"></a>00619         }
<a name="l00620"></a>00620 
<a name="l00621"></a>00621 <span class="keywordtype">bool</span> indexLessThan(ClassAuxIPE* &amp;s1,ClassAuxIPE* &amp;s2)
<a name="l00622"></a>00622         {
<a name="l00623"></a>00623         <span class="keywordflow">return</span> s1-&gt;index &lt; s2-&gt;index;
<a name="l00624"></a>00624         }
<a name="l00625"></a>00625 
<a name="l00626"></a>00626 <span class="keywordtype">bool</span> indexLessThanF(ClassAuxIPE_F* &amp;s1,ClassAuxIPE_F* &amp;s2)
<a name="l00627"></a>00627         {
<a name="l00628"></a>00628         <span class="keywordflow">return</span> s1-&gt;index &lt; s2-&gt;index;
<a name="l00629"></a>00629         }
<a name="l00630"></a>00630 
<a name="l00631"></a>00631 <span class="keyword">inline</span> <span class="keywordtype">double</span> costElimination(<span class="keyword">const</span> <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> &amp;polyline,<span class="keywordtype">int</span> ia, <span class="keywordtype">int</span> ib, <span class="keywordtype">int</span> ic)
<a name="l00632"></a>00632         {
<a name="l00633"></a>00633         <span class="keywordtype">double</span>   xA,yA,xB,yB,xC,yC;
<a name="l00634"></a>00634         xA = polyline[ia].x(); yA=polyline[ia].y();
<a name="l00635"></a>00635         xB = polyline[ib].x(); yB=polyline[ib].y();
<a name="l00636"></a>00636         xC = polyline[ic].x(); yC=polyline[ic].y();
<a name="l00637"></a>00637         <span class="keywordflow">if</span>((xA != xC) or (yA != yC))
<a name="l00638"></a>00638                 <span class="keywordflow">return</span> ABS(xA*(yC-yB) + xB*(yA-yC) + xC*(yB-yA)) / sqrt((xA-xC)*(xA-xC)+(yA-yC)*(yA-yC));
<a name="l00639"></a>00639         <span class="keywordflow">else</span>
<a name="l00640"></a>00640                 <span class="keywordflow">return</span> sqrt((xB-xC)*(xB-xC)+(yB-yC)*(yB-yC));
<a name="l00641"></a>00641         }
<a name="l00642"></a>00642 
<a name="l00643"></a>00643 <span class="keyword">inline</span> <span class="keywordtype">double</span> costEliminationF(<span class="keyword">const</span> <a class="code" href="classQVPolylineF.html" title="Floating point polyline representation.">QVPolylineF</a> &amp;polyline,<span class="keywordtype">int</span> ia, <span class="keywordtype">int</span> ib, <span class="keywordtype">int</span> ic)
<a name="l00644"></a>00644         {
<a name="l00645"></a>00645         <span class="keywordtype">double</span>   xA,yA,xB,yB,xC,yC;
<a name="l00646"></a>00646         xA = polyline[ia].x(); yA=polyline[ia].y();
<a name="l00647"></a>00647         xB = polyline[ib].x(); yB=polyline[ib].y();
<a name="l00648"></a>00648         xC = polyline[ic].x(); yC=polyline[ic].y();
<a name="l00649"></a>00649         <span class="keywordflow">if</span>((xA != xC) or (yA != yC))
<a name="l00650"></a>00650                 <span class="keywordflow">return</span> ABS(xA*(yC-yB) + xB*(yA-yC) + xC*(yB-yA)) / sqrt((xA-xC)*(xA-xC)+(yA-yC)*(yA-yC));
<a name="l00651"></a>00651         <span class="keywordflow">else</span>
<a name="l00652"></a>00652                 <span class="keywordflow">return</span> sqrt((xB-xC)*(xB-xC)+(yB-yC)*(yB-yC));
<a name="l00653"></a>00653         }
<a name="l00654"></a>00654 
<a name="l00655"></a>00655 <span class="keyword">class </span>auxLine {
<a name="l00656"></a>00656         <span class="keyword">public</span>:
<a name="l00657"></a>00657         auxLine(<span class="keywordtype">double</span> l1,<span class="keywordtype">double</span> l2,<span class="keywordtype">double</span> l3,<span class="keywordtype">bool</span> ok) : l1(l1),l2(l2),l3(l3),ok(ok) {};
<a name="l00658"></a>00658         <span class="keywordtype">double</span> l1,l2,l3;
<a name="l00659"></a>00659         <span class="keywordtype">bool</span> ok;
<a name="l00660"></a>00660 };
<a name="l00661"></a>00661 
<a name="l00662"></a>00662 <span class="keyword">class </span>auxLine_F {
<a name="l00663"></a>00663         <span class="keyword">public</span>:
<a name="l00664"></a>00664         auxLine_F(<span class="keywordtype">double</span> l1,<span class="keywordtype">double</span> l2,<span class="keywordtype">double</span> l3,<span class="keywordtype">bool</span> ok) : l1(l1),l2(l2),l3(l3),ok(ok) {};
<a name="l00665"></a>00665         <span class="keywordtype">double</span> l1,l2,l3;
<a name="l00666"></a>00666         <span class="keywordtype">bool</span> ok;
<a name="l00667"></a>00667 };
<a name="l00668"></a>00668 <span class="preprocessor">#endif // DOXYGEN_IGNORE_THIS</span>
<a name="l00669"></a>00669 <span class="preprocessor"></span>
<a name="l00670"></a>00670 <span class="preprocessor">#ifdef QVMATRIXALGEBRA_AVAILABLE</span>
<a name="l00671"></a><a class="code" href="group__qvip.html#ga69b4cc8c2c9561eb4623cb86ddd16fff">00671</a> <span class="preprocessor"></span><span class="keywordtype">double</span> <a class="code" href="group__qvip.html#ga69b4cc8c2c9561eb4623cb86ddd16fff" title="Eliminates points of a polyline of small shape contribution using the IPE algorithmThis...">IterativePointElimination</a>(<span class="keyword">const</span> <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> &amp;polyline, <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> &amp;result,
<a name="l00672"></a>00672         <span class="keyword">const</span> <span class="keywordtype">double</span> param, <span class="keywordtype">bool</span> maxNumberOfPointsMethod,<span class="keywordtype">bool</span> intersectLines,
<a name="l00673"></a>00673         <span class="keywordtype">double</span> *max_removed_cost)
<a name="l00674"></a>00674         {
<a name="l00675"></a>00675         <span class="keyword">const</span> uInt tot_siz = polyline.size();
<a name="l00676"></a>00676         QList&lt;ClassAuxIPE*&gt; list;
<a name="l00677"></a>00677 
<a name="l00678"></a>00678         <span class="comment">// We start with an empty list:</span>
<a name="l00679"></a>00679         result.clear();
<a name="l00680"></a>00680 
<a name="l00681"></a>00681         <span class="comment">// Maximum removed cost initialized to zero:</span>
<a name="l00682"></a>00682         <span class="keywordflow">if</span>(max_removed_cost != NULL) *max_removed_cost = 0.0;
<a name="l00683"></a>00683 
<a name="l00684"></a>00684         <span class="comment">// Only for polylines with 3 points or more; otherwise, the same</span>
<a name="l00685"></a>00685         <span class="comment">// input polyline is returned:</span>
<a name="l00686"></a>00686         <span class="keywordflow">if</span>(polyline.size()&lt;3)
<a name="l00687"></a>00687                 {
<a name="l00688"></a>00688                 result = polyline;
<a name="l00689"></a>00689                 <span class="keywordflow">return</span> FLT_MAX;
<a name="l00690"></a>00690                 }
<a name="l00691"></a>00691 
<a name="l00692"></a>00692         <span class="comment">// Initialization of main data structure:</span>
<a name="l00693"></a>00693         <span class="keywordflow">for</span>(uInt i=0;i&lt;tot_siz;i++)
<a name="l00694"></a>00694                 list.push_back(<span class="keyword">new</span> ClassAuxIPE);
<a name="l00695"></a>00695 
<a name="l00696"></a>00696         <span class="keywordflow">for</span>(uInt i=0;i&lt;tot_siz;i++)
<a name="l00697"></a>00697                 {
<a name="l00698"></a>00698                 <span class="keywordtype">int</span> ia = (i==0)?tot_siz-1:i-1, ib = i, ic = (i==tot_siz-1)?0:i+1;
<a name="l00699"></a>00699                 list[i]-&gt;cost = costElimination(polyline,ia,ib,ic);
<a name="l00700"></a>00700                 list[i]-&gt;index = ib;
<a name="l00701"></a>00701                 list[i]-&gt;prev = list[ia];
<a name="l00702"></a>00702                 list[i]-&gt;next = list[ic];
<a name="l00703"></a>00703                 }
<a name="l00704"></a>00704         <span class="keywordflow">if</span>(not polyline.closed) <span class="comment">// If not closed, never eliminate end points:</span>
<a name="l00705"></a>00705                 {
<a name="l00706"></a>00706                 list[0]-&gt;cost = FLT_MAX;
<a name="l00707"></a>00707                 list[tot_siz-1]-&gt;cost = FLT_MAX;
<a name="l00708"></a>00708                 }
<a name="l00709"></a>00709         qSort(list.begin(),list.end(), costLessThan);
<a name="l00710"></a>00710 
<a name="l00711"></a>00711         <span class="comment">// Main loop:</span>
<a name="l00712"></a>00712         <span class="keywordflow">while</span>(TRUE)
<a name="l00713"></a>00713                 {
<a name="l00714"></a>00714                 <span class="comment">// Stop condition:</span>
<a name="l00715"></a>00715                 <span class="keywordflow">if</span>( (list.size() == 3) or <span class="comment">// Minimal size of a polyline.</span>
<a name="l00716"></a>00716                     ((not maxNumberOfPointsMethod) and (list[0]-&gt;cost &gt; param)) or
<a name="l00717"></a>00717                     ((maxNumberOfPointsMethod) and
<a name="l00718"></a>00718                      (list.size() &lt;= <span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(param))) )
<a name="l00719"></a>00719                         <span class="keywordflow">break</span>;
<a name="l00720"></a>00720 
<a name="l00721"></a>00721                 <span class="comment">// Removal of best point (first in the list): </span>
<a name="l00722"></a>00722                 ClassAuxIPE *elem = list.takeAt(0),
<a name="l00723"></a>00723                             *elemPrev = list.takeAt(list.indexOf(elem-&gt;prev)),
<a name="l00724"></a>00724                             *elemNext = list.takeAt(list.indexOf(elem-&gt;next));
<a name="l00725"></a>00725                 elemPrev-&gt;next = elem-&gt;next;
<a name="l00726"></a>00726                 elemNext-&gt;prev = elem-&gt;prev;
<a name="l00727"></a>00727                 <span class="keywordflow">if</span>(elemPrev-&gt;cost != FLT_MAX)
<a name="l00728"></a>00728                         elemPrev-&gt;cost = costElimination(polyline,elemPrev-&gt;prev-&gt;index,
<a name="l00729"></a>00729                                                                 elemPrev-&gt;index,
<a name="l00730"></a>00730                                                                 elemPrev-&gt;next-&gt;index);
<a name="l00731"></a>00731                 <span class="keywordflow">if</span>(elemNext-&gt;cost != FLT_MAX)
<a name="l00732"></a>00732                 elemNext-&gt;cost = costElimination(polyline,elemNext-&gt;prev-&gt;index,
<a name="l00733"></a>00733                                                         elemNext-&gt;index,
<a name="l00734"></a>00734                                                         elemNext-&gt;next-&gt;index);
<a name="l00735"></a>00735 
<a name="l00736"></a>00736                 <span class="comment">// Binary (fast) insertion of neighbours in data structure:</span>
<a name="l00737"></a>00737                 <span class="keywordtype">int</span> here;
<a name="l00738"></a>00738                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i=0;i&lt;2;i++)
<a name="l00739"></a>00739                         {
<a name="l00740"></a>00740                         ClassAuxIPE* newelem = ((i==0)?elemNext:elemPrev);
<a name="l00741"></a>00741                         <span class="keywordtype">int</span> first=0,last=list.size()-1;
<a name="l00742"></a>00742                         <span class="keywordflow">while</span> (first &lt;= last) {
<a name="l00743"></a>00743                                 <span class="keywordtype">int</span> mid = (first + last) / 2;
<a name="l00744"></a>00744                                 <span class="keywordflow">if</span> (newelem-&gt;cost &gt; list[mid]-&gt;cost)
<a name="l00745"></a>00745                                         first = mid + 1;
<a name="l00746"></a>00746                                 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (newelem-&gt;cost &lt; list[mid]-&gt;cost)
<a name="l00747"></a>00747                                         last = mid - 1;
<a name="l00748"></a>00748                                 <span class="keywordflow">else</span>
<a name="l00749"></a>00749                                         {
<a name="l00750"></a>00750                                         here = mid;
<a name="l00751"></a>00751                                         <span class="keywordflow">break</span>;
<a name="l00752"></a>00752                                         }
<a name="l00753"></a>00753                         }
<a name="l00754"></a>00754                         <span class="keywordflow">if</span>(first&gt;last)
<a name="l00755"></a>00755                                 here=first;
<a name="l00756"></a>00756                         list.insert(here,newelem);
<a name="l00757"></a>00757 
<a name="l00758"></a>00758                         }
<a name="l00759"></a>00759 
<a name="l00760"></a>00760                 <span class="keywordflow">if</span>(max_removed_cost != NULL)
<a name="l00761"></a>00761                         <span class="keywordflow">if</span>(elem-&gt;cost &gt; *max_removed_cost)
<a name="l00762"></a>00762                                 *max_removed_cost = elem-&gt;cost;
<a name="l00763"></a>00763                 <span class="keyword">delete</span> elem;
<a name="l00764"></a>00764                 }
<a name="l00765"></a>00765 
<a name="l00766"></a>00766         <span class="comment">// We will return the cost of the first non deleted point:</span>
<a name="l00767"></a>00767         <span class="keywordtype">double</span> return_value = list.first()-&gt;cost;
<a name="l00768"></a>00768 
<a name="l00769"></a>00769         <span class="comment">// Once IPE finished, sort the list by position in original polyline:</span>
<a name="l00770"></a>00770         qSort(list.begin(),list.end(),indexLessThan);
<a name="l00771"></a>00771 
<a name="l00772"></a>00772         <span class="comment">// Now, postprocess, fitting lines:</span>
<a name="l00773"></a>00773         QList&lt;ClassAuxIPE*&gt;::iterator it = list.begin();
<a name="l00774"></a>00774         <span class="keywordflow">if</span>(intersectLines)
<a name="l00775"></a>00775                 {
<a name="l00776"></a>00776                 <span class="comment">// Line intersection computation (could be subpixel, in fact...):</span>
<a name="l00777"></a>00777                 <span class="keywordtype">double</span> ratio_eig=1.0;
<a name="l00778"></a>00778                 QList&lt;auxLine&gt; lines;
<a name="l00779"></a>00779                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i=0;i&lt;list.size();i++)
<a name="l00780"></a>00780                         {
<a name="l00781"></a>00781                         <span class="comment">// If not closed, do not need to compute last line:</span>
<a name="l00782"></a>00782                         <span class="keywordflow">if</span>((not polyline.closed) and (i==list.size()-1))
<a name="l00783"></a>00783                                 <span class="keywordflow">break</span>;
<a name="l00784"></a>00784                         <span class="keywordtype">int</span> i1 = list[i]-&gt;index;
<a name="l00785"></a>00785                         <span class="keywordtype">int</span> i2 = list[(i+1)%list.size()]-&gt;index;
<a name="l00786"></a>00786                         <span class="keywordflow">if</span>(i2&lt;i1) i2 += tot_siz;
<a name="l00787"></a>00787                         <span class="keywordtype">int</span> dist = i2-i1+1;
<a name="l00788"></a>00788 <span class="preprocessor">                        #define MIN_PIXELS_IPE_LINE 15</span>
<a name="l00789"></a>00789 <span class="preprocessor"></span>                        <span class="keywordflow">if</span>(dist &gt;= MIN_PIXELS_IPE_LINE)
<a name="l00790"></a>00790                                 {
<a name="l00791"></a>00791                                 i1 = (i1+dist/5)%tot_siz;
<a name="l00792"></a>00792                                 i2 = (i2-dist/5)%tot_siz;
<a name="l00793"></a>00793                                 dist = dist-2*(dist/5);
<a name="l00794"></a>00794                                 }
<a name="l00795"></a>00795                         <span class="keywordflow">else</span> 
<a name="l00796"></a>00796                                 {
<a name="l00797"></a>00797                                 dist = i2-i1+1;
<a name="l00798"></a>00798                                 i1 = i1%tot_siz;
<a name="l00799"></a>00799                                 i2 = i2%tot_siz;
<a name="l00800"></a>00800                                 }
<a name="l00801"></a>00801         
<a name="l00802"></a>00802                         <span class="keywordtype">double</span> x=0,y=0,xx=0,xy=0,yy=0;
<a name="l00803"></a>00803                         uInt j=i1;
<a name="l00804"></a>00804                         <span class="keywordflow">do</span>
<a name="l00805"></a>00805                                 {
<a name="l00806"></a>00806                                 x += polyline[j].x();
<a name="l00807"></a>00807                                 y += polyline[j].y();
<a name="l00808"></a>00808                                 xx += polyline[j].x()*polyline[j].x();
<a name="l00809"></a>00809                                 xy += polyline[j].x()*polyline[j].y();
<a name="l00810"></a>00810                                 yy += polyline[j].y()*polyline[j].y();
<a name="l00811"></a>00811                                 j = (j+1)%tot_siz;
<a name="l00812"></a>00812                                 } <span class="keywordflow">while</span>(j!=(i2+1)%tot_siz);
<a name="l00813"></a>00813                         <span class="keywordtype">double</span> l1,l2,l3;
<a name="l00814"></a>00814                         x /= dist; y /= dist; xx /= dist; xy /= dist; yy /= dist;
<a name="l00815"></a>00815                         <span class="comment">// If line does not fit well, just put old point instead of intersection:</span>
<a name="l00816"></a>00816                         <span class="comment">//#ifdef GSL_AVAILABLE</span>
<a name="l00817"></a>00817                         ratio_eig = homogLineFromMoments(x,y,xx,xy,yy,l1,l2,l3);
<a name="l00818"></a>00818                         <span class="comment">//#else</span>
<a name="l00819"></a>00819                         <span class="comment">//std::cerr &lt;&lt; &quot;[IterativePointElimination] ERROR: GSL is required to intersect lines&quot;&lt;&lt; std::endl;</span>
<a name="l00820"></a>00820                         <span class="comment">//exit(0);</span>
<a name="l00821"></a>00821                         <span class="comment">//#endif</span>
<a name="l00822"></a>00822 
<a name="l00823"></a>00823                         lines.push_back(auxLine(l1,l2,l3,ratio_eig &lt; 0.1));
<a name="l00824"></a>00824                         }
<a name="l00825"></a>00825 
<a name="l00826"></a>00826                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i=0;i&lt;list.size();i++)
<a name="l00827"></a>00827                         {
<a name="l00828"></a>00828                         QPoint oldPoint = polyline[list[i]-&gt;index];
<a name="l00829"></a>00829                         <span class="keywordflow">if</span>( (not polyline.closed) and ((i==0) or (i==list.size()-1)))
<a name="l00830"></a>00830                                 {
<a name="l00831"></a>00831                                 <span class="comment">// If not closed, just include end points:</span>
<a name="l00832"></a>00832                                 result.append(oldPoint);
<a name="l00833"></a>00833                                 <span class="keywordflow">continue</span>;
<a name="l00834"></a>00834                                 }
<a name="l00835"></a>00835                         <span class="keywordtype">int</span> ant = (i-1+list.size())%list.size();
<a name="l00836"></a>00836                         <span class="keywordtype">int</span> post = (i+1)%list.size();
<a name="l00837"></a>00837                         <span class="keywordtype">double</span>  newx = (lines[i].l2)*(lines[ant].l3) - (lines[i].l3)*(lines[ant].l2);
<a name="l00838"></a>00838                         <span class="keywordtype">double</span>  newy = -(lines[i].l1)*(lines[ant].l3) + (lines[i].l3)*(lines[ant].l1);
<a name="l00839"></a>00839                         <span class="keywordtype">double</span>  newz = (lines[i].l1)*(lines[ant].l2) - (lines[i].l2)*(lines[ant].l1);
<a name="l00840"></a>00840                         <span class="keywordflow">if</span> ( (not lines[i].ok) or (not lines[ant].ok) or <span class="comment">// Bad segment</span>
<a name="l00841"></a>00841                                 (fabs(newz) &lt; EPSILON) ) <span class="comment">// Lines too parallel</span>
<a name="l00842"></a>00842                                 result.append(oldPoint);
<a name="l00843"></a>00843                         <span class="keywordflow">else</span>
<a name="l00844"></a>00844                                 {
<a name="l00845"></a>00845                                 <span class="keywordtype">int</span> nx = qRound(newx/newz);
<a name="l00846"></a>00846                                 <span class="keywordtype">int</span> ny = qRound(newy/newz);
<a name="l00847"></a>00847                                 <span class="comment">// Only consider intersection if it is inside</span>
<a name="l00848"></a>00848                                 <span class="comment">// a maximum radius circle around the old point</span>
<a name="l00849"></a>00849                                 <span class="comment">// (relative to its nearer previous/next point</span>
<a name="l00850"></a>00850                                 <span class="comment">// in polyline):</span>
<a name="l00851"></a>00851                                 <span class="keywordtype">double</span> dist =
<a name="l00852"></a>00852                                         sqrt((nx-oldPoint.x())*(nx-oldPoint.x()) +
<a name="l00853"></a>00853                                              (ny-oldPoint.y())*(ny-oldPoint.y()));
<a name="l00854"></a>00854                                 QPoint prevPoint = polyline[list[ant]-&gt;index],
<a name="l00855"></a>00855                                         nextPoint = polyline[list[post]-&gt;index];
<a name="l00856"></a>00856                                 <span class="keywordtype">double</span> minDist =
<a name="l00857"></a>00857                                         qMin(
<a name="l00858"></a>00858                                         sqrt((prevPoint.x()-oldPoint.x())*(prevPoint.x()-oldPoint.x()) +
<a name="l00859"></a>00859                                         (prevPoint.y()-oldPoint.y())*(prevPoint.y()-oldPoint.y())),
<a name="l00860"></a>00860                                         sqrt((nextPoint.x()-oldPoint.x())*(nextPoint.x()-oldPoint.x()) +
<a name="l00861"></a>00861                                         (nextPoint.y()-oldPoint.y())*(nextPoint.y()-oldPoint.y()))
<a name="l00862"></a>00862                                         );
<a name="l00863"></a>00863                                 <span class="keywordflow">if</span>(dist &lt; 0.2*minDist)
<a name="l00864"></a>00864                                         result.append(QPoint(nx,ny));
<a name="l00865"></a>00865                                 <span class="keywordflow">else</span>
<a name="l00866"></a>00866                                         result.append(oldPoint);
<a name="l00867"></a>00867                                 }
<a name="l00868"></a>00868                         }
<a name="l00869"></a>00869                 }
<a name="l00870"></a>00870         <span class="keywordflow">else</span> 
<a name="l00871"></a>00871                 {
<a name="l00872"></a>00872                 <span class="comment">// No postprocess, simply store the resulting points in result polyline.</span>
<a name="l00873"></a>00873                 it = list.begin();
<a name="l00874"></a>00874                 <span class="keywordflow">while</span>(it != list.end())
<a name="l00875"></a>00875                         {
<a name="l00876"></a>00876                                 result.append(polyline.at((*it)-&gt;index));
<a name="l00877"></a>00877                                 it++;
<a name="l00878"></a>00878                         }
<a name="l00879"></a>00879                 }
<a name="l00880"></a>00880 
<a name="l00881"></a>00881         <span class="comment">// Free memory of remaining structure:</span>
<a name="l00882"></a>00882         <span class="keywordflow">while</span> (!list.isEmpty())
<a name="l00883"></a>00883                 <span class="keyword">delete</span> list.takeFirst();
<a name="l00884"></a>00884 
<a name="l00885"></a>00885         <span class="comment">// Polyline type and direction are the same of the original polyline:</span>
<a name="l00886"></a>00886         result.closed = polyline.closed;
<a name="l00887"></a>00887         result.direction = polyline.direction;
<a name="l00888"></a>00888 
<a name="l00889"></a>00889         <span class="comment">// We return the cost of the first non deleted point:</span>
<a name="l00890"></a>00890         <span class="keywordflow">return</span> return_value;
<a name="l00891"></a>00891         }
<a name="l00892"></a>00892 
<a name="l00893"></a><a class="code" href="group__qvip.html#ga38efea2a64358c2fcf43fc302b0b3595">00893</a> <span class="keywordtype">double</span> <a class="code" href="group__qvip.html#ga69b4cc8c2c9561eb4623cb86ddd16fff" title="Eliminates points of a polyline of small shape contribution using the IPE algorithmThis...">IterativePointElimination</a>(<span class="keyword">const</span> <a class="code" href="classQVPolylineF.html" title="Floating point polyline representation.">QVPolylineF</a> &amp;polyline, <a class="code" href="classQVPolylineF.html" title="Floating point polyline representation.">QVPolylineF</a> &amp;result,
<a name="l00894"></a>00894         <span class="keyword">const</span> <span class="keywordtype">double</span> param, <span class="keywordtype">bool</span> maxNumberOfPointsMethod,<span class="keywordtype">bool</span> intersectLines,
<a name="l00895"></a>00895         <span class="keywordtype">double</span> *max_removed_cost)
<a name="l00896"></a>00896         {
<a name="l00897"></a>00897         <span class="keyword">const</span> uInt tot_siz = polyline.size();
<a name="l00898"></a>00898         QList&lt;ClassAuxIPE_F*&gt; list;
<a name="l00899"></a>00899 
<a name="l00900"></a>00900         <span class="comment">// We start with an empty list:</span>
<a name="l00901"></a>00901         result.clear();
<a name="l00902"></a>00902 
<a name="l00903"></a>00903         <span class="comment">// Maximum removed cost initialized to zero:</span>
<a name="l00904"></a>00904         <span class="keywordflow">if</span>(max_removed_cost != NULL) *max_removed_cost = 0.0;
<a name="l00905"></a>00905 
<a name="l00906"></a>00906         <span class="comment">// Only for polylines with 3 points or more; otherwise, the same</span>
<a name="l00907"></a>00907         <span class="comment">// input polyline is returned:</span>
<a name="l00908"></a>00908         <span class="keywordflow">if</span>(polyline.size()&lt;3)
<a name="l00909"></a>00909                 {
<a name="l00910"></a>00910                 result = polyline;
<a name="l00911"></a>00911                 <span class="keywordflow">return</span> FLT_MAX;
<a name="l00912"></a>00912                 }
<a name="l00913"></a>00913 
<a name="l00914"></a>00914         <span class="comment">// Initialization of main data structure:</span>
<a name="l00915"></a>00915         <span class="keywordflow">for</span>(uInt i=0;i&lt;tot_siz;i++)
<a name="l00916"></a>00916                 list.push_back(<span class="keyword">new</span> ClassAuxIPE_F);
<a name="l00917"></a>00917 
<a name="l00918"></a>00918         <span class="keywordflow">for</span>(uInt i=0;i&lt;tot_siz;i++)
<a name="l00919"></a>00919                 {
<a name="l00920"></a>00920                 <span class="keywordtype">int</span> ia = (i==0)?tot_siz-1:i-1, ib = i, ic = (i==tot_siz-1)?0:i+1;
<a name="l00921"></a>00921                 list[i]-&gt;cost = costEliminationF(polyline,ia,ib,ic);
<a name="l00922"></a>00922                 list[i]-&gt;index = ib;
<a name="l00923"></a>00923                 list[i]-&gt;prev = list[ia];
<a name="l00924"></a>00924                 list[i]-&gt;next = list[ic];
<a name="l00925"></a>00925                 }
<a name="l00926"></a>00926         <span class="keywordflow">if</span>(not polyline.closed) <span class="comment">// If not closed, never eliminate end points:</span>
<a name="l00927"></a>00927                 {
<a name="l00928"></a>00928                 list[0]-&gt;cost = FLT_MAX;
<a name="l00929"></a>00929                 list[tot_siz-1]-&gt;cost = FLT_MAX;
<a name="l00930"></a>00930                 }
<a name="l00931"></a>00931         qSort(list.begin(),list.end(),costLessThanF);
<a name="l00932"></a>00932 
<a name="l00933"></a>00933         <span class="comment">// Main loop:</span>
<a name="l00934"></a>00934         <span class="keywordflow">while</span>(TRUE)
<a name="l00935"></a>00935                 {
<a name="l00936"></a>00936                 <span class="comment">// Stop condition:</span>
<a name="l00937"></a>00937                 <span class="keywordflow">if</span>( (list.size() == 3) or <span class="comment">// Minimal size of a polyline.</span>
<a name="l00938"></a>00938                     ((not maxNumberOfPointsMethod) and (list[0]-&gt;cost &gt; param)) or
<a name="l00939"></a>00939                     ((maxNumberOfPointsMethod) and
<a name="l00940"></a>00940                      (list.size() &lt;= <span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(param))) )
<a name="l00941"></a>00941                         <span class="keywordflow">break</span>;
<a name="l00942"></a>00942 
<a name="l00943"></a>00943                 <span class="comment">// Removal of best point (first in the list): </span>
<a name="l00944"></a>00944                 ClassAuxIPE_F *elem = list.takeAt(0),
<a name="l00945"></a>00945                             *elemPrev = list.takeAt(list.indexOf(elem-&gt;prev)),
<a name="l00946"></a>00946                             *elemNext = list.takeAt(list.indexOf(elem-&gt;next));
<a name="l00947"></a>00947                 elemPrev-&gt;next = elem-&gt;next;
<a name="l00948"></a>00948                 elemNext-&gt;prev = elem-&gt;prev;
<a name="l00949"></a>00949                 <span class="keywordflow">if</span>(elemPrev-&gt;cost != FLT_MAX)
<a name="l00950"></a>00950                         elemPrev-&gt;cost = costEliminationF(polyline,elemPrev-&gt;prev-&gt;index,
<a name="l00951"></a>00951                                                                 elemPrev-&gt;index,
<a name="l00952"></a>00952                                                                 elemPrev-&gt;next-&gt;index);
<a name="l00953"></a>00953                 <span class="keywordflow">if</span>(elemNext-&gt;cost != FLT_MAX)
<a name="l00954"></a>00954                 elemNext-&gt;cost = costEliminationF(polyline,elemNext-&gt;prev-&gt;index,
<a name="l00955"></a>00955                                                         elemNext-&gt;index,
<a name="l00956"></a>00956                                                         elemNext-&gt;next-&gt;index);
<a name="l00957"></a>00957 
<a name="l00958"></a>00958                 <span class="comment">// Binary (fast) insertion of neighbours in data structure:</span>
<a name="l00959"></a>00959                 <span class="keywordtype">int</span> here;
<a name="l00960"></a>00960                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i=0;i&lt;2;i++)
<a name="l00961"></a>00961                         {
<a name="l00962"></a>00962                         ClassAuxIPE_F* newelem = ((i==0)?elemNext:elemPrev);
<a name="l00963"></a>00963                         <span class="keywordtype">int</span> first=0,last=list.size()-1;
<a name="l00964"></a>00964                         <span class="keywordflow">while</span> (first &lt;= last) {
<a name="l00965"></a>00965                                 <span class="keywordtype">int</span> mid = (first + last) / 2;
<a name="l00966"></a>00966                                 <span class="keywordflow">if</span> (newelem-&gt;cost &gt; list[mid]-&gt;cost)
<a name="l00967"></a>00967                                         first = mid + 1;
<a name="l00968"></a>00968                                 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (newelem-&gt;cost &lt; list[mid]-&gt;cost)
<a name="l00969"></a>00969                                         last = mid - 1;
<a name="l00970"></a>00970                                 <span class="keywordflow">else</span>
<a name="l00971"></a>00971                                         {
<a name="l00972"></a>00972                                         here = mid;
<a name="l00973"></a>00973                                         <span class="keywordflow">break</span>;
<a name="l00974"></a>00974                                         }
<a name="l00975"></a>00975                         }
<a name="l00976"></a>00976                         <span class="keywordflow">if</span>(first&gt;last)
<a name="l00977"></a>00977                                 here=first;
<a name="l00978"></a>00978                         list.insert(here,newelem);
<a name="l00979"></a>00979 
<a name="l00980"></a>00980                         }
<a name="l00981"></a>00981 
<a name="l00982"></a>00982                 <span class="keywordflow">if</span>(max_removed_cost != NULL)
<a name="l00983"></a>00983                         <span class="keywordflow">if</span>(elem-&gt;cost &gt; *max_removed_cost)
<a name="l00984"></a>00984                                 *max_removed_cost = elem-&gt;cost;
<a name="l00985"></a>00985                 <span class="keyword">delete</span> elem;
<a name="l00986"></a>00986                 }
<a name="l00987"></a>00987 
<a name="l00988"></a>00988         <span class="comment">// We will return the cost of the first non deleted point:</span>
<a name="l00989"></a>00989         <span class="keywordtype">double</span> return_value = list.first()-&gt;cost;
<a name="l00990"></a>00990 
<a name="l00991"></a>00991         <span class="comment">// Once IPE finished, sort the list by position in original polyline:</span>
<a name="l00992"></a>00992         qSort(list.begin(),list.end(),indexLessThanF);
<a name="l00993"></a>00993 
<a name="l00994"></a>00994         <span class="comment">// Now, postprocess, fitting lines:</span>
<a name="l00995"></a>00995         QList&lt;ClassAuxIPE_F*&gt;::iterator it = list.begin();
<a name="l00996"></a>00996         <span class="keywordflow">if</span>(intersectLines)
<a name="l00997"></a>00997                 {
<a name="l00998"></a>00998                 <span class="comment">// Line intersection computation (could be subpixel, in fact...):</span>
<a name="l00999"></a>00999                 <span class="keywordtype">double</span> ratio_eig=1.0;
<a name="l01000"></a>01000                 QList&lt;auxLine_F&gt; lines;
<a name="l01001"></a>01001                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i=0;i&lt;list.size();i++)
<a name="l01002"></a>01002                         {
<a name="l01003"></a>01003                         <span class="comment">// If not closed, do not need to compute last line:</span>
<a name="l01004"></a>01004                         <span class="keywordflow">if</span>((not polyline.closed) and (i==list.size()-1))
<a name="l01005"></a>01005                                 <span class="keywordflow">break</span>;
<a name="l01006"></a>01006                         <span class="keywordtype">int</span> i1 = list[i]-&gt;index;
<a name="l01007"></a>01007                         <span class="keywordtype">int</span> i2 = list[(i+1)%list.size()]-&gt;index;
<a name="l01008"></a>01008                         <span class="keywordflow">if</span>(i2&lt;i1) i2 += tot_siz;
<a name="l01009"></a>01009                         <span class="keywordtype">int</span> dist = i2-i1+1;
<a name="l01010"></a>01010 <span class="preprocessor">                        #define MIN_PIXELS_IPE_LINE 15</span>
<a name="l01011"></a>01011 <span class="preprocessor"></span>                        <span class="keywordflow">if</span>(dist &gt;= MIN_PIXELS_IPE_LINE)
<a name="l01012"></a>01012                                 {
<a name="l01013"></a>01013                                 i1 = (i1+dist/5)%tot_siz;
<a name="l01014"></a>01014                                 i2 = (i2-dist/5)%tot_siz;
<a name="l01015"></a>01015                                 dist = dist-2*(dist/5);
<a name="l01016"></a>01016                                 }
<a name="l01017"></a>01017                         <span class="keywordflow">else</span> 
<a name="l01018"></a>01018                                 {
<a name="l01019"></a>01019                                 dist = i2-i1+1;
<a name="l01020"></a>01020                                 i1 = i1%tot_siz;
<a name="l01021"></a>01021                                 i2 = i2%tot_siz;
<a name="l01022"></a>01022                                 }
<a name="l01023"></a>01023         
<a name="l01024"></a>01024                         <span class="keywordtype">double</span> x=0,y=0,xx=0,xy=0,yy=0;
<a name="l01025"></a>01025                         uInt j=i1;
<a name="l01026"></a>01026                         <span class="keywordflow">do</span>
<a name="l01027"></a>01027                                 {
<a name="l01028"></a>01028                                 x += polyline[j].x();
<a name="l01029"></a>01029                                 y += polyline[j].y();
<a name="l01030"></a>01030                                 xx += polyline[j].x()*polyline[j].x();
<a name="l01031"></a>01031                                 xy += polyline[j].x()*polyline[j].y();
<a name="l01032"></a>01032                                 yy += polyline[j].y()*polyline[j].y();
<a name="l01033"></a>01033                                 j = (j+1)%tot_siz;
<a name="l01034"></a>01034                                 } <span class="keywordflow">while</span>(j!=(i2+1)%tot_siz);
<a name="l01035"></a>01035                         <span class="keywordtype">double</span> l1,l2,l3;
<a name="l01036"></a>01036                         x /= dist; y /= dist; xx /= dist; xy /= dist; yy /= dist;
<a name="l01037"></a>01037 
<a name="l01038"></a>01038                         <span class="comment">// If line does not fit well, just put old point instead of intersection:</span>
<a name="l01039"></a>01039                         <span class="comment">//#ifdef GSL_AVAILABLE</span>
<a name="l01040"></a>01040                         ratio_eig = homogLineFromMoments(x,y,xx,xy,yy,l1,l2,l3);
<a name="l01041"></a>01041                         <span class="comment">//#else</span>
<a name="l01042"></a>01042                         <span class="comment">//std::cerr &lt;&lt; &quot;[IterativePointElimination] ERROR: GSL is required to intersect lines&quot;&lt;&lt; std::endl;</span>
<a name="l01043"></a>01043                         <span class="comment">//exit(0);</span>
<a name="l01044"></a>01044                         <span class="comment">//#endif</span>
<a name="l01045"></a>01045 
<a name="l01046"></a>01046                         lines.push_back(auxLine_F(l1,l2,l3,ratio_eig &lt; 0.1));
<a name="l01047"></a>01047                         }
<a name="l01048"></a>01048 
<a name="l01049"></a>01049                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i=0;i&lt;list.size();i++)
<a name="l01050"></a>01050                         {
<a name="l01051"></a>01051                         QPointF oldPoint = polyline[list[i]-&gt;index];
<a name="l01052"></a>01052                         <span class="keywordflow">if</span>( (not polyline.closed) and ((i==0) or (i==list.size()-1)))
<a name="l01053"></a>01053                                 {
<a name="l01054"></a>01054                                 <span class="comment">// If not closed, just include end points:</span>
<a name="l01055"></a>01055                                 result.append(oldPoint);
<a name="l01056"></a>01056                                 <span class="keywordflow">continue</span>;
<a name="l01057"></a>01057                                 }
<a name="l01058"></a>01058                         <span class="keywordtype">int</span> ant = (i-1+list.size())%list.size();
<a name="l01059"></a>01059                         <span class="keywordtype">int</span> post = (i+1)%list.size();
<a name="l01060"></a>01060                         <span class="keywordtype">double</span>  newx = (lines[i].l2)*(lines[ant].l3) - (lines[i].l3)*(lines[ant].l2);
<a name="l01061"></a>01061                         <span class="keywordtype">double</span>  newy = -(lines[i].l1)*(lines[ant].l3) + (lines[i].l3)*(lines[ant].l1);
<a name="l01062"></a>01062                         <span class="keywordtype">double</span>  newz = (lines[i].l1)*(lines[ant].l2) - (lines[i].l2)*(lines[ant].l1);
<a name="l01063"></a>01063                         <span class="keywordflow">if</span> ( (not lines[i].ok) or (not lines[ant].ok) or <span class="comment">// Bad segment</span>
<a name="l01064"></a>01064                                 (fabs(newz) &lt; EPSILON) ) <span class="comment">// Lines too parallel</span>
<a name="l01065"></a>01065                                 result.append(oldPoint);
<a name="l01066"></a>01066                         <span class="keywordflow">else</span>
<a name="l01067"></a>01067                                 {
<a name="l01068"></a>01068                                 <span class="keywordtype">double</span> nx = newx/newz;
<a name="l01069"></a>01069                                 <span class="keywordtype">double</span> ny = newy/newz;
<a name="l01070"></a>01070                                 <span class="comment">// Only consider intersection if it is inside</span>
<a name="l01071"></a>01071                                 <span class="comment">// a maximum radius circle around the old point</span>
<a name="l01072"></a>01072                                 <span class="comment">// (relative to its nearer previous/next point</span>
<a name="l01073"></a>01073                                 <span class="comment">// in polyline):</span>
<a name="l01074"></a>01074                                 <span class="keywordtype">double</span> dist =
<a name="l01075"></a>01075                                         sqrt((nx-oldPoint.x())*(nx-oldPoint.x()) +
<a name="l01076"></a>01076                                              (ny-oldPoint.y())*(ny-oldPoint.y()));
<a name="l01077"></a>01077                                 QPointF prevPoint = polyline[list[ant]-&gt;index],
<a name="l01078"></a>01078                                         nextPoint = polyline[list[post]-&gt;index];
<a name="l01079"></a>01079                                 <span class="keywordtype">double</span> minDist =
<a name="l01080"></a>01080                                         qMin(
<a name="l01081"></a>01081                                         sqrt((prevPoint.x()-oldPoint.x())*(prevPoint.x()-oldPoint.x()) +
<a name="l01082"></a>01082                                         (prevPoint.y()-oldPoint.y())*(prevPoint.y()-oldPoint.y())),
<a name="l01083"></a>01083                                         sqrt((nextPoint.x()-oldPoint.x())*(nextPoint.x()-oldPoint.x()) +
<a name="l01084"></a>01084                                         (nextPoint.y()-oldPoint.y())*(nextPoint.y()-oldPoint.y()))
<a name="l01085"></a>01085                                         );
<a name="l01086"></a>01086                                 <span class="keywordflow">if</span>(dist &lt; 0.2*minDist)
<a name="l01087"></a>01087                                         result.append(QPointF(nx,ny));
<a name="l01088"></a>01088                                 <span class="keywordflow">else</span>
<a name="l01089"></a>01089                                         result.append(oldPoint);
<a name="l01090"></a>01090                                 }
<a name="l01091"></a>01091                         }
<a name="l01092"></a>01092                 }
<a name="l01093"></a>01093         <span class="keywordflow">else</span> <span class="comment">// LAPACK_AVAILABLE</span>
<a name="l01094"></a>01094                 {
<a name="l01095"></a>01095                 <span class="comment">// No postprocess, simply store the resulting points in result polyline.</span>
<a name="l01096"></a>01096                 it = list.begin();
<a name="l01097"></a>01097                 <span class="keywordflow">while</span>(it != list.end())
<a name="l01098"></a>01098                         {
<a name="l01099"></a>01099                                 result.append(polyline.at((*it)-&gt;index));
<a name="l01100"></a>01100                                 it++;
<a name="l01101"></a>01101                         }
<a name="l01102"></a>01102                 }
<a name="l01103"></a>01103 
<a name="l01104"></a>01104         <span class="comment">// Free memory of remaining structure:</span>
<a name="l01105"></a>01105         <span class="keywordflow">while</span> (!list.isEmpty())
<a name="l01106"></a>01106                 <span class="keyword">delete</span> list.takeFirst();
<a name="l01107"></a>01107 
<a name="l01108"></a>01108         <span class="comment">// Polyline type and direction are the same of the original polyline:</span>
<a name="l01109"></a>01109         result.closed = polyline.closed;
<a name="l01110"></a>01110         result.direction = polyline.direction;
<a name="l01111"></a>01111 
<a name="l01112"></a>01112         <span class="comment">// We return the cost of the first non deleted point:</span>
<a name="l01113"></a>01113         <span class="keywordflow">return</span> return_value;
<a name="l01114"></a>01114         }
<a name="l01115"></a>01115 <span class="preprocessor">#else</span>
<a name="l01116"></a>01116 <span class="preprocessor"></span><span class="keywordtype">double</span> <a class="code" href="group__qvip.html#ga69b4cc8c2c9561eb4623cb86ddd16fff" title="Eliminates points of a polyline of small shape contribution using the IPE algorithmThis...">IterativePointElimination</a>(<span class="keyword">const</span> <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> &amp;polyline, <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> &amp;result,
<a name="l01117"></a>01117         <span class="keyword">const</span> <span class="keywordtype">double</span> param, <span class="keywordtype">bool</span> maxNumberOfPointsMethod,<span class="keywordtype">bool</span> intersectLines,
<a name="l01118"></a>01118         <span class="keywordtype">double</span> *max_removed_cost)
<a name="l01119"></a>01119         {
<a name="l01120"></a>01120         result = polyline;
<a name="l01121"></a>01121         std::cout &lt;&lt; <span class="stringliteral">&quot;Warning: IterativePointElimination requires GSL, MKL or LAPACK functionality enabled to work properly.&quot;</span> &lt;&lt; std::endl;
<a name="l01122"></a>01122         <span class="keywordflow">return</span> 0.0;
<a name="l01123"></a>01123         }
<a name="l01124"></a>01124 
<a name="l01125"></a>01125 
<a name="l01126"></a>01126 <span class="keywordtype">double</span> <a class="code" href="group__qvip.html#ga69b4cc8c2c9561eb4623cb86ddd16fff" title="Eliminates points of a polyline of small shape contribution using the IPE algorithmThis...">IterativePointElimination</a>(<span class="keyword">const</span> <a class="code" href="classQVPolylineF.html" title="Floating point polyline representation.">QVPolylineF</a> &amp;polyline, <a class="code" href="classQVPolylineF.html" title="Floating point polyline representation.">QVPolylineF</a> &amp;result,
<a name="l01127"></a>01127         <span class="keyword">const</span> <span class="keywordtype">double</span> param, <span class="keywordtype">bool</span> maxNumberOfPointsMethod,<span class="keywordtype">bool</span> intersectLines,
<a name="l01128"></a>01128         <span class="keywordtype">double</span> *max_removed_cost)
<a name="l01129"></a>01129         {
<a name="l01130"></a>01130         result = polyline;
<a name="l01131"></a>01131         std::cout &lt;&lt; <span class="stringliteral">&quot;Warning: IterativePointElimination requires GSL, MKL or LAPACK functionality enabled to work properly.&quot;</span> &lt;&lt; std::endl;
<a name="l01132"></a>01132         <span class="keywordflow">return</span> 0.0;
<a name="l01133"></a>01133         }
<a name="l01134"></a>01134 
<a name="l01135"></a>01135 <span class="preprocessor">#endif // QVMATRIXALGEBRA_AVAILABLE</span>
<a name="l01136"></a>01136 <span class="preprocessor"></span>
<a name="l01138"></a>01138 <span class="comment">// Get borders and contours</span>
<a name="l01139"></a>01139 <span class="comment">// Direction-number             Y</span>
<a name="l01140"></a>01140 <span class="comment">//      NE-7    N-0     NW-1    |</span>
<a name="l01141"></a>01141 <span class="comment">//      E-6     *       W-2     v</span>
<a name="l01142"></a>01142 <span class="comment">//      SE-5    S-4     SW-3</span>
<a name="l01143"></a>01143 <span class="comment">// X --&gt;</span>
<a name="l01144"></a>01144 <span class="comment">//                                              N       NO      O       SO      S       SE      E       NE</span>
<a name="l01145"></a>01145 <span class="preprocessor">#ifndef DOXYGEN_IGNORE_THIS</span>
<a name="l01146"></a>01146 <span class="preprocessor"></span><span class="keyword">const</span> <span class="keywordtype">char</span>      coorX8Connect[8] =      {       0,      1,      1,      1,      0,      -1,     -1,     -1      };
<a name="l01147"></a>01147 <span class="keyword">const</span> <span class="keywordtype">char</span>      coorY8Connect[8] =      {       -1,     -1,     0,      1,      1,      1,      0,      -1      };
<a name="l01148"></a>01148 <span class="keyword">const</span> <span class="keywordtype">char</span>      coorX4Connect[4] =      {       0,              1,              0,              -1,             };
<a name="l01149"></a>01149 <span class="keyword">const</span> <span class="keywordtype">char</span>      coorY4Connect[4] =      {       -1,             0,              1,              0,              };
<a name="l01150"></a>01150 <span class="keyword">const</span> <span class="keywordtype">char</span>      coorX4Diag[8] =         {               1,              1,              -1,             -1      };
<a name="l01151"></a>01151 <span class="keyword">const</span> <span class="keywordtype">char</span>      coorY4Diag[8] =         {               -1,             1,              1,              -1      };
<a name="l01152"></a>01152 <span class="preprocessor">#endif</span>
<a name="l01153"></a>01153 <span class="preprocessor"></span>
<a name="l01154"></a>01154 <span class="comment">// Auxiliar function for border extraction. It gets a border point, and the direction where there is one of the outside of the connected-set pixels.</span>
<a name="l01155"></a>01155 <span class="preprocessor">#ifndef DOXYGEN_IGNORE_THIS</span>
<a name="l01156"></a>01156 <span class="preprocessor"></span><a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> getConnectedSetBorderContourThresholdFromBorderPoint(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <span class="keyword">const</span> <span class="keywordtype">int</span> startPointX, <span class="keyword">const</span> <span class="keywordtype">int</span> startPointY, <span class="keyword">const</span> uChar threshold)
<a name="l01157"></a>01157         {
<a name="l01158"></a>01158         <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> lista;
<a name="l01159"></a>01159 
<a name="l01160"></a>01160         lista.closed = <span class="keyword">true</span>;
<a name="l01161"></a>01161         lista.append(QPoint(startPointX, startPointY));
<a name="l01162"></a>01162 
<a name="l01163"></a>01163         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(uChar,image);
<a name="l01164"></a>01164         QRect roi = image.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>();
<a name="l01165"></a>01165 
<a name="l01166"></a>01166         Q_ASSERT_X(roi.contains(startPointX, startPointY), <span class="stringliteral">&quot;getContourThresholdFromBorderPoint&quot;</span>, <span class="stringliteral">&quot;start point out of image ROI&quot;</span>);
<a name="l01167"></a>01167         Q_ASSERT_X(<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, startPointX, startPointY, 0) &gt;= threshold, <span class="stringliteral">&quot;getContourThresholdFromBorderPoint&quot;</span>, <span class="stringliteral">&quot;start point is not contained in a connected set&quot;</span>);
<a name="l01168"></a>01168 
<a name="l01169"></a>01169         <span class="comment">// We check this is not an interior pixel, neither a solitary one.</span>
<a name="l01170"></a>01170         <span class="comment">// Also we look for a neighbour pixel not belonging to any connected set.</span>
<a name="l01171"></a>01171         uChar searchDir = 128, numOuterPixels = 0;
<a name="l01172"></a>01172         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i&lt;8; i++)
<a name="l01173"></a>01173                 {
<a name="l01174"></a>01174                 <span class="keywordtype">int</span> x =  startPointX +coorX8Connect[i], y =  startPointY +coorY8Connect[i];
<a name="l01175"></a>01175                 <span class="keywordflow">if</span> (!roi.contains(x, y))
<a name="l01176"></a>01176                         {
<a name="l01177"></a>01177                         numOuterPixels++;
<a name="l01178"></a>01178                         searchDir = i;
<a name="l01179"></a>01179                         }
<a name="l01180"></a>01180                 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, x, y,0) &lt; threshold)
<a name="l01181"></a>01181                         {
<a name="l01182"></a>01182                         numOuterPixels++;
<a name="l01183"></a>01183                         searchDir = i;
<a name="l01184"></a>01184                         }
<a name="l01185"></a>01185                 }
<a name="l01186"></a>01186 
<a name="l01187"></a>01187         <span class="comment">// Case we receive an interior pixel, raise assert.</span>
<a name="l01188"></a>01188         Q_ASSERT_X(searchDir &lt; 8, <span class="stringliteral">&quot;getContourThresholdFromBorderPoint&quot;</span>, <span class="stringliteral">&quot;start point is inside the set, not in the border&quot;</span>);
<a name="l01189"></a>01189 
<a name="l01190"></a>01190         <span class="comment">// Case we have a solitary pixel, we return that pixel.</span>
<a name="l01191"></a>01191         <span class="keywordflow">if</span> (numOuterPixels == 8)
<a name="l01192"></a>01192                 <span class="keywordflow">return</span> lista;
<a name="l01193"></a>01193 
<a name="l01194"></a>01194         <span class="comment">// We insert each point of the border contour, inserting it to the point list.</span>
<a name="l01195"></a>01195         <span class="keywordtype">int</span> sumSearchDir = 0, actualPointX = startPointX, actualPointY = startPointY;
<a name="l01196"></a>01196         <span class="keywordflow">while</span> (<span class="keyword">true</span>)
<a name="l01197"></a>01197                 {
<a name="l01198"></a>01198                 <span class="comment">// We search for the next point belonging to the contour.</span>
<a name="l01199"></a>01199                 uChar d;
<a name="l01200"></a>01200                 <span class="keywordtype">int</span>     nextPointX, nextPointY;
<a name="l01201"></a>01201                 <span class="keywordflow">for</span> (d = 0; d &lt; 8; d++)
<a name="l01202"></a>01202                         {
<a name="l01203"></a>01203                         searchDir = (searchDir+1)%8;
<a name="l01204"></a>01204                         nextPointX = actualPointX + coorX8Connect[searchDir];
<a name="l01205"></a>01205                         nextPointY = actualPointY + coorY8Connect[searchDir];
<a name="l01206"></a>01206                         <span class="keywordflow">if</span> (roi.contains(nextPointX, nextPointY))
<a name="l01207"></a>01207                                 <span class="keywordflow">if</span> ( (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, nextPointX, nextPointY,0) &gt;= threshold) )
<a name="l01208"></a>01208                                         <span class="keywordflow">break</span>;
<a name="l01209"></a>01209                         }
<a name="l01210"></a>01210 
<a name="l01211"></a>01211                 sumSearchDir += d - 3;
<a name="l01212"></a>01212 
<a name="l01213"></a>01213                 actualPointX = nextPointX;
<a name="l01214"></a>01214                 actualPointY = nextPointY;
<a name="l01215"></a>01215 
<a name="l01216"></a>01216                 <span class="keywordflow">if</span> ( <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, actualPointX, actualPointY,0) &lt; threshold )
<a name="l01217"></a>01217                         <span class="keywordflow">break</span>;
<a name="l01218"></a>01218 
<a name="l01219"></a>01219                 <span class="keywordflow">if</span> ( startPointX == actualPointX &amp;&amp; startPointY == actualPointY)
<a name="l01220"></a>01220                         <span class="keywordflow">break</span>;
<a name="l01221"></a>01221 
<a name="l01222"></a>01222                 lista.append(QPoint(actualPointX, actualPointY));
<a name="l01223"></a>01223                 searchDir = searchDir + 4;
<a name="l01224"></a>01224                 }
<a name="l01225"></a>01225 
<a name="l01226"></a>01226         lista.direction = (sumSearchDir &gt;= 0);
<a name="l01227"></a>01227         <span class="keywordflow">return</span> lista;
<a name="l01228"></a>01228         }
<a name="l01229"></a>01229 
<a name="l01230"></a>01230 <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> getConnectedSetBorderContourThresholdFromBorderPoint(<span class="keyword">const</span> <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;uShort&gt;</a> &amp;image, <span class="keyword">const</span> <span class="keywordtype">int</span> startPointX, <span class="keyword">const</span> <span class="keywordtype">int</span> startPointY, <span class="keyword">const</span> uShort threshold)
<a name="l01231"></a>01231         {
<a name="l01232"></a>01232         <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> lista;
<a name="l01233"></a>01233 
<a name="l01234"></a>01234         lista.closed = <span class="keyword">true</span>;
<a name="l01235"></a>01235         lista.append(QPoint(startPointX, startPointY));
<a name="l01236"></a>01236 
<a name="l01237"></a>01237         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(uShort,image);
<a name="l01238"></a>01238         QRect roi = image.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>();
<a name="l01239"></a>01239 
<a name="l01240"></a>01240         Q_ASSERT_X(roi.contains(startPointX, startPointY), <span class="stringliteral">&quot;getContourThresholdFromBorderPoint&quot;</span>, <span class="stringliteral">&quot;start point out of image ROI&quot;</span>);
<a name="l01241"></a>01241         Q_ASSERT_X(<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, startPointX, startPointY, 0) &gt;= threshold, <span class="stringliteral">&quot;getContourThresholdFromBorderPoint&quot;</span>, <span class="stringliteral">&quot;start point is not contained in a connected set&quot;</span>);
<a name="l01242"></a>01242 
<a name="l01243"></a>01243         <span class="comment">// We check this is not an interior pixel, neither a solitary one.</span>
<a name="l01244"></a>01244         <span class="comment">// Also we look for a neighbour pixel not belonging to any connected set.</span>
<a name="l01245"></a>01245         uShort searchDir = 128, numOuterPixels = 0;
<a name="l01246"></a>01246         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i&lt;8; i++)
<a name="l01247"></a>01247                 {
<a name="l01248"></a>01248                 <span class="keywordtype">int</span> x =  startPointX +coorX8Connect[i], y =  startPointY +coorY8Connect[i];
<a name="l01249"></a>01249                 <span class="keywordflow">if</span> (!roi.contains(x, y))
<a name="l01250"></a>01250                         {
<a name="l01251"></a>01251                         numOuterPixels++;
<a name="l01252"></a>01252                         searchDir = i;
<a name="l01253"></a>01253                         }
<a name="l01254"></a>01254                 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, x, y,0) &lt; threshold)
<a name="l01255"></a>01255                         {
<a name="l01256"></a>01256                         numOuterPixels++;
<a name="l01257"></a>01257                         searchDir = i;
<a name="l01258"></a>01258                         }
<a name="l01259"></a>01259                 }
<a name="l01260"></a>01260 
<a name="l01261"></a>01261         <span class="comment">// Case we receive an interior pixel, raise assert.</span>
<a name="l01262"></a>01262         Q_ASSERT_X(searchDir &lt; 8, <span class="stringliteral">&quot;getContourThresholdFromBorderPoint&quot;</span>, <span class="stringliteral">&quot;start point is inside the set, not in the border&quot;</span>);
<a name="l01263"></a>01263 
<a name="l01264"></a>01264         <span class="comment">// Case we have a solitary pixel, we return that pixel.</span>
<a name="l01265"></a>01265         <span class="keywordflow">if</span> (numOuterPixels == 8)
<a name="l01266"></a>01266                 <span class="keywordflow">return</span> lista;
<a name="l01267"></a>01267 
<a name="l01268"></a>01268         <span class="comment">// We insert each point of the border contour, inserting it to the point list.</span>
<a name="l01269"></a>01269         <span class="keywordtype">int</span> sumSearchDir = 0, actualPointX = startPointX, actualPointY = startPointY;
<a name="l01270"></a>01270         <span class="keywordflow">while</span> (<span class="keyword">true</span>)
<a name="l01271"></a>01271                 {
<a name="l01272"></a>01272                 <span class="comment">// We search for the next point belonging to the contour.</span>
<a name="l01273"></a>01273                 uShort d;
<a name="l01274"></a>01274                 <span class="keywordtype">int</span>     nextPointX, nextPointY;
<a name="l01275"></a>01275                 <span class="keywordflow">for</span> (d = 0; d &lt; 8; d++)
<a name="l01276"></a>01276                         {
<a name="l01277"></a>01277                         searchDir = (searchDir+1)%8;
<a name="l01278"></a>01278                         nextPointX = actualPointX + coorX8Connect[searchDir];
<a name="l01279"></a>01279                         nextPointY = actualPointY + coorY8Connect[searchDir];
<a name="l01280"></a>01280                         <span class="keywordflow">if</span> (roi.contains(nextPointX, nextPointY))
<a name="l01281"></a>01281                                 <span class="keywordflow">if</span> ( (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, nextPointX, nextPointY,0) &gt;= threshold) )
<a name="l01282"></a>01282                                         <span class="keywordflow">break</span>;
<a name="l01283"></a>01283                         }
<a name="l01284"></a>01284 
<a name="l01285"></a>01285                 sumSearchDir += d - 3;
<a name="l01286"></a>01286 
<a name="l01287"></a>01287                 actualPointX = nextPointX;
<a name="l01288"></a>01288                 actualPointY = nextPointY;
<a name="l01289"></a>01289 
<a name="l01290"></a>01290                 <span class="keywordflow">if</span> ( <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, actualPointX, actualPointY,0) &lt; threshold )
<a name="l01291"></a>01291                         <span class="keywordflow">break</span>;
<a name="l01292"></a>01292 
<a name="l01293"></a>01293                 <span class="keywordflow">if</span> ( startPointX == actualPointX &amp;&amp; startPointY == actualPointY)
<a name="l01294"></a>01294                         <span class="keywordflow">break</span>;
<a name="l01295"></a>01295 
<a name="l01296"></a>01296                 lista.append(QPoint(actualPointX, actualPointY));
<a name="l01297"></a>01297                 searchDir = searchDir + 4;
<a name="l01298"></a>01298                 }
<a name="l01299"></a>01299 
<a name="l01300"></a>01300         lista.direction = (sumSearchDir &gt;= 0);
<a name="l01301"></a>01301         <span class="keywordflow">return</span> lista;
<a name="l01302"></a>01302         }
<a name="l01303"></a>01303 
<a name="l01304"></a>01304 
<a name="l01305"></a>01305 
<a name="l01306"></a>01306 
<a name="l01307"></a>01307 <span class="preprocessor">#endif</span>
<a name="l01308"></a>01308 <span class="preprocessor"></span>
<a name="l01309"></a>01309 <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> getConnectedSetBorderContourThreshold(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <span class="keyword">const</span> QPoint startPoint, <span class="keyword">const</span> uChar threshold)
<a name="l01310"></a>01310         {
<a name="l01311"></a>01311         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(uChar,image);
<a name="l01312"></a>01312         <span class="keyword">const</span> QRect roi = image.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>();
<a name="l01313"></a>01313 
<a name="l01314"></a>01314         <span class="keywordtype">int</span> col = startPoint.x(), row = startPoint.y();
<a name="l01315"></a>01315 
<a name="l01316"></a>01316         <span class="keywordflow">if</span> (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, col, row,0) &lt; threshold)
<a name="l01317"></a>01317                 <span class="keywordflow">return</span> <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a>();
<a name="l01318"></a>01318 
<a name="l01319"></a>01319         <span class="keywordflow">while</span> (roi.contains(col+1, row))
<a name="l01320"></a>01320                 {
<a name="l01321"></a>01321                 <span class="keywordflow">if</span> ( <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, col+1, row,0) &lt; threshold )
<a name="l01322"></a>01322                         <span class="keywordflow">break</span>;
<a name="l01323"></a>01323                 col++;
<a name="l01324"></a>01324                 }
<a name="l01325"></a>01325 
<a name="l01326"></a>01326         <span class="keywordflow">return</span> getConnectedSetBorderContourThresholdFromBorderPoint(image, col, row, threshold);
<a name="l01327"></a>01327         }
<a name="l01328"></a>01328 
<a name="l01329"></a>01329 <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> getConnectedSetBorderContourThreshold(<span class="keyword">const</span> <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;uShort&gt;</a> &amp;image, <span class="keyword">const</span> QPoint startPoint, <span class="keyword">const</span> uShort threshold)
<a name="l01330"></a>01330         {
<a name="l01331"></a>01331         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(uShort,image);
<a name="l01332"></a>01332         <span class="keyword">const</span> QRect roi = image.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>();
<a name="l01333"></a>01333 
<a name="l01334"></a>01334         <span class="keywordtype">int</span> col = startPoint.x(), row = startPoint.y();
<a name="l01335"></a>01335 
<a name="l01336"></a>01336         <span class="keywordflow">if</span> (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, col, row,0) &lt; threshold)
<a name="l01337"></a>01337                 <span class="keywordflow">return</span> <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a>();
<a name="l01338"></a>01338 
<a name="l01339"></a>01339         <span class="keywordflow">while</span> (roi.contains(col+1, row))
<a name="l01340"></a>01340                 {
<a name="l01341"></a>01341                 <span class="keywordflow">if</span> ( <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, col+1, row,0) &lt; threshold )
<a name="l01342"></a>01342                         <span class="keywordflow">break</span>;
<a name="l01343"></a>01343                 col++;
<a name="l01344"></a>01344                 }
<a name="l01345"></a>01345 
<a name="l01346"></a>01346         <span class="keywordflow">return</span> getConnectedSetBorderContourThresholdFromBorderPoint(image, col, row, threshold);
<a name="l01347"></a>01347         }
<a name="l01348"></a>01348 
<a name="l01349"></a><a class="code" href="group__qvip.html#gacfe3100b9457c7fe9965a0b0e937ba24">01349</a> QList&lt;QVPolyline&gt; <a class="code" href="group__qvip.html#gacfe3100b9457c7fe9965a0b0e937ba24" title="Obtains the borders of connected sets of pixels, containing gray-scale values equal...">getConnectedSetBorderContoursThreshold</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage &lt;uChar&gt;</a> &amp;image, <span class="keyword">const</span> uChar threshold)
<a name="l01350"></a>01350         {
<a name="l01351"></a>01351         qDebug() &lt;&lt; <span class="stringliteral">&quot;getPolylinesThreshold()&quot;</span>;
<a name="l01352"></a>01352         <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> mask(image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>()+1, image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>()+1);
<a name="l01353"></a>01353         <a class="code" href="group__qvippIDEAIF.html#gae2bed87200a1f753701bf5fc1e7a476b" title="Sets pixels in the image buffer to a constant value.">Set</a>(0, mask);
<a name="l01354"></a>01354 
<a name="l01355"></a>01355         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(uChar,image);
<a name="l01356"></a>01356         <a class="code" href="group__qvip.html#ga42904f931068a3ea3f6bdb90861d1dc1" title="Initializes image to be written or read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_WRITE</a>(uChar,mask);
<a name="l01357"></a>01357 
<a name="l01358"></a>01358         <span class="keyword">const</span> QRect roi = image.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>();
<a name="l01359"></a>01359 
<a name="l01360"></a>01360         QList&lt;QVPolyline&gt; polylineList;
<a name="l01361"></a>01361 
<a name="l01362"></a>01362         <span class="comment">// We look for pixels contained in a connected set (gray-level value &gt;= threshold) in the image</span>
<a name="l01363"></a>01363         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> row = roi.y(); row &lt; roi.y() + roi.height(); row++)
<a name="l01364"></a>01364                 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> col = roi.x(); col &lt; roi.y() + roi.width(); col++)
<a name="l01365"></a>01365                         {
<a name="l01366"></a>01366                         <span class="comment">// If we find any pixel like that, we can be sure (because the search we did) it belongs to it&#39;s border.</span>
<a name="l01367"></a>01367                         <span class="keywordflow">if</span> (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, col, row,0) &gt;= threshold)
<a name="l01368"></a>01368                                 {
<a name="l01369"></a>01369                                 <span class="comment">// if pixel is not marked, we get it&#39;s contour</span>
<a name="l01370"></a>01370                                 <span class="keywordflow">if</span> ( !<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(mask, col, row,0) )
<a name="l01371"></a>01371                                         {
<a name="l01372"></a>01372                                         <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> lista = getConnectedSetBorderContourThresholdFromBorderPoint(image, col, row, threshold);
<a name="l01373"></a>01373                                         polylineList.append(lista);
<a name="l01374"></a>01374 
<a name="l01375"></a>01375                                         QListIterator&lt;QPoint&gt; iterator(lista);
<a name="l01376"></a>01376                                         <span class="keywordflow">for</span> (QPoint previous = iterator.next(), actual; iterator.hasNext(); previous = actual)
<a name="l01377"></a>01377                                                 {
<a name="l01378"></a>01378                                                 actual = iterator.next();
<a name="l01379"></a>01379                                                 <span class="keywordflow">foreach</span> (QPoint point, QVPolyline::line(actual.x(), actual.y(), previous.x(), previous.y()))
<a name="l01380"></a>01380                                                         <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(mask, point.x(), point.y(),0) = <span class="keyword">true</span>;
<a name="l01381"></a>01381                                                 }
<a name="l01382"></a>01382                                         }
<a name="l01383"></a>01383 
<a name="l01384"></a>01384                                 <span class="comment">// We ensure next pixel we process will not belong to a connected set.</span>
<a name="l01385"></a>01385                                 <span class="keywordflow">while</span> (roi.contains(col+1, row))
<a name="l01386"></a>01386                                         {
<a name="l01387"></a>01387                                         <span class="keywordflow">if</span> ( <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, col+1, row,0) &lt; threshold )
<a name="l01388"></a>01388                                                 <span class="keywordflow">break</span>;
<a name="l01389"></a>01389                                         col++;
<a name="l01390"></a>01390                                         }
<a name="l01391"></a>01391 
<a name="l01392"></a>01392                                 <span class="comment">// This is for the case in which we find an internal contour, that has not been processed and marked.</span>
<a name="l01393"></a>01393                                 <span class="keywordflow">if</span> ( !<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(mask, col, row,0) )
<a name="l01394"></a>01394                                         {
<a name="l01395"></a>01395                                         <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> lista = getConnectedSetBorderContourThresholdFromBorderPoint(image, col, row, threshold);
<a name="l01396"></a>01396                                         polylineList.append(lista);
<a name="l01397"></a>01397 
<a name="l01398"></a>01398                                         QListIterator&lt;QPoint&gt; iterator(lista);
<a name="l01399"></a>01399                                         <span class="keywordflow">for</span> (QPoint previous = iterator.next(), actual; iterator.hasNext(); previous = actual)
<a name="l01400"></a>01400                                                 {
<a name="l01401"></a>01401                                                 actual = iterator.next();
<a name="l01402"></a>01402                                                 <span class="keywordflow">foreach</span> (QPoint point, QVPolyline::line(actual.x(), actual.y(), previous.x(), previous.y()))
<a name="l01403"></a>01403                                                         <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(mask, point.x(), point.y(),0) = <span class="keyword">true</span>;
<a name="l01404"></a>01404                                                 }
<a name="l01405"></a>01405                                         }
<a name="l01406"></a>01406                                 }
<a name="l01407"></a>01407 
<a name="l01408"></a>01408                         }
<a name="l01409"></a>01409         qDebug() &lt;&lt; <span class="stringliteral">&quot;getPolylinesThreshold():&quot;</span>&lt;&lt; polylineList.size() &lt;&lt; <span class="stringliteral">&quot;contours obtained&quot;</span>;
<a name="l01410"></a>01410         qDebug() &lt;&lt; <span class="stringliteral">&quot;getPolylinesThreshold() &lt;~ return&quot;</span>;
<a name="l01411"></a>01411         <span class="keywordflow">return</span> polylineList;
<a name="l01412"></a>01412         }
<a name="l01413"></a>01413 
<a name="l01414"></a>01414 
<a name="l01415"></a>01415 QList&lt;QVPolyline&gt; <a class="code" href="group__qvip.html#gacfe3100b9457c7fe9965a0b0e937ba24" title="Obtains the borders of connected sets of pixels, containing gray-scale values equal...">getConnectedSetBorderContoursThreshold</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage &lt;uShort&gt;</a> &amp;image, <span class="keyword">const</span> uShort threshold)
<a name="l01416"></a>01416         {
<a name="l01417"></a>01417         qDebug() &lt;&lt; <span class="stringliteral">&quot;getPolylinesThreshold()&quot;</span>;
<a name="l01418"></a>01418         <a class="code" href="classQVImage.html" title="Image representation class for the QVision.">QVImage&lt;uShort&gt;</a> mask(image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>()+1, image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>()+1);
<a name="l01419"></a>01419         <a class="code" href="group__qvippIDEAIF.html#gae2bed87200a1f753701bf5fc1e7a476b" title="Sets pixels in the image buffer to a constant value.">Set</a>(0, mask);
<a name="l01420"></a>01420 
<a name="l01421"></a>01421         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(uShort,image);
<a name="l01422"></a>01422         <a class="code" href="group__qvip.html#ga42904f931068a3ea3f6bdb90861d1dc1" title="Initializes image to be written or read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_WRITE</a>(uShort,mask);
<a name="l01423"></a>01423 
<a name="l01424"></a>01424         <span class="keyword">const</span> QRect roi = image.<a class="code" href="classQVGenericImage.html#a55132f8ba36904516dcf384039c670e4" title="Method for obtaining actual region of interest for image.">getROI</a>();
<a name="l01425"></a>01425 
<a name="l01426"></a>01426         QList&lt;QVPolyline&gt; polylineList;
<a name="l01427"></a>01427 
<a name="l01428"></a>01428         <span class="comment">// We look for pixels contained in a connected set (gray-level value &gt;= threshold) in the image</span>
<a name="l01429"></a>01429         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> row = roi.y(); row &lt; roi.y() + roi.height(); row++)
<a name="l01430"></a>01430                 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> col = roi.x(); col &lt; roi.y() + roi.width(); col++)
<a name="l01431"></a>01431                         {
<a name="l01432"></a>01432                         <span class="comment">// If we find any pixel like that, we can be sure (because the search we did) it belongs to it&#39;s border.</span>
<a name="l01433"></a>01433                         <span class="keywordflow">if</span> (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, col, row,0) &gt;= threshold)
<a name="l01434"></a>01434                                 {
<a name="l01435"></a>01435                                 <span class="comment">// if pixel is not marked, we get it&#39;s contour</span>
<a name="l01436"></a>01436                                 <span class="keywordflow">if</span> ( !<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(mask, col, row,0) )
<a name="l01437"></a>01437                                         {
<a name="l01438"></a>01438                                         <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> lista = getConnectedSetBorderContourThresholdFromBorderPoint(image, col, row, threshold);
<a name="l01439"></a>01439                                         polylineList.append(lista);
<a name="l01440"></a>01440 
<a name="l01441"></a>01441                                         QListIterator&lt;QPoint&gt; iterator(lista);
<a name="l01442"></a>01442                                         <span class="keywordflow">for</span> (QPoint previous = iterator.next(), actual; iterator.hasNext(); previous = actual)
<a name="l01443"></a>01443                                                 {
<a name="l01444"></a>01444                                                 actual = iterator.next();
<a name="l01445"></a>01445                                                 <span class="keywordflow">foreach</span> (QPoint point, QVPolyline::line(actual.x(), actual.y(), previous.x(), previous.y()))
<a name="l01446"></a>01446                                                         <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(mask, point.x(), point.y(),0) = <span class="keyword">true</span>;
<a name="l01447"></a>01447                                                 }
<a name="l01448"></a>01448                                         }
<a name="l01449"></a>01449 
<a name="l01450"></a>01450                                 <span class="comment">// We ensure next pixel we process will not belong to a connected set.</span>
<a name="l01451"></a>01451                                 <span class="keywordflow">while</span> (roi.contains(col+1, row))
<a name="l01452"></a>01452                                         {
<a name="l01453"></a>01453                                         <span class="keywordflow">if</span> ( <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, col+1, row,0) &lt; threshold )
<a name="l01454"></a>01454                                                 <span class="keywordflow">break</span>;
<a name="l01455"></a>01455                                         col++;
<a name="l01456"></a>01456                                         }
<a name="l01457"></a>01457 
<a name="l01458"></a>01458                                 <span class="comment">// This is for the case in which we find an internal contour, that has not been processed and marked.</span>
<a name="l01459"></a>01459                                 <span class="keywordflow">if</span> ( !<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(mask, col, row,0) )
<a name="l01460"></a>01460                                         {
<a name="l01461"></a>01461                                         <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> lista = getConnectedSetBorderContourThresholdFromBorderPoint(image, col, row, threshold);
<a name="l01462"></a>01462                                         polylineList.append(lista);
<a name="l01463"></a>01463 
<a name="l01464"></a>01464                                         QListIterator&lt;QPoint&gt; iterator(lista);
<a name="l01465"></a>01465                                         <span class="keywordflow">for</span> (QPoint previous = iterator.next(), actual; iterator.hasNext(); previous = actual)
<a name="l01466"></a>01466                                                 {
<a name="l01467"></a>01467                                                 actual = iterator.next();
<a name="l01468"></a>01468                                                 <span class="keywordflow">foreach</span> (QPoint point, QVPolyline::line(actual.x(), actual.y(), previous.x(), previous.y()))
<a name="l01469"></a>01469                                                         <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(mask, point.x(), point.y(),0) = <span class="keyword">true</span>;
<a name="l01470"></a>01470                                                 }
<a name="l01471"></a>01471                                         }
<a name="l01472"></a>01472                                 }
<a name="l01473"></a>01473 
<a name="l01474"></a>01474                         }
<a name="l01475"></a>01475         qDebug() &lt;&lt; <span class="stringliteral">&quot;getPolylinesThreshold():&quot;</span>&lt;&lt; polylineList.size() &lt;&lt; <span class="stringliteral">&quot;contours obtained&quot;</span>;
<a name="l01476"></a>01476         qDebug() &lt;&lt; <span class="stringliteral">&quot;getPolylinesThreshold() &lt;~ return&quot;</span>;
<a name="l01477"></a>01477         <span class="keywordflow">return</span> polylineList;
<a name="l01478"></a>01478         }
<a name="l01479"></a>01479 
<a name="l01480"></a>01480 
<a name="l01481"></a>01481 
<a name="l01483"></a>01483 
<a name="l01484"></a>01484 <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> getLineContourThreshold4Connectivity(<a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <span class="keyword">const</span> QPoint point, <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> &amp;polyline, <span class="keyword">const</span> uChar threshold, <span class="keywordtype">bool</span> reverse)
<a name="l01485"></a>01485         {
<a name="l01486"></a>01486         <span class="keyword">const</span> uInt cols = image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(), rows = image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>();
<a name="l01487"></a>01487         <a class="code" href="group__qvip.html#ga42904f931068a3ea3f6bdb90861d1dc1" title="Initializes image to be written or read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_WRITE</a>(uChar, image);
<a name="l01488"></a>01488 
<a name="l01489"></a>01489         uInt lastDir = 666, coorX = point.x(), coorY = point.y();
<a name="l01490"></a>01490 
<a name="l01491"></a>01491         qDebug() &lt;&lt; <span class="stringliteral">&quot;\tContour: new contour&quot;</span>;
<a name="l01492"></a>01492 
<a name="l01493"></a>01493         forever {
<a name="l01494"></a>01494                 qDebug() &lt;&lt; <span class="stringliteral">&quot;\tContour:\tAppending point (&quot;</span> &lt;&lt; coorX &lt;&lt; <span class="stringliteral">&quot;, &quot;</span> &lt;&lt; coorY &lt;&lt; <span class="stringliteral">&quot;)&quot;</span>;
<a name="l01495"></a>01495                 <span class="keywordflow">if</span> (reverse)
<a name="l01496"></a>01496                         polyline.prepend(QPoint(coorX, coorY));
<a name="l01497"></a>01497                 <span class="keywordflow">else</span>
<a name="l01498"></a>01498                         polyline.append(QPoint(coorX, coorY));
<a name="l01499"></a>01499 
<a name="l01500"></a>01500                 <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, coorX, coorY, 0) = 0;
<a name="l01501"></a>01501 
<a name="l01502"></a>01502                 uInt dir;
<a name="l01503"></a>01503                 <span class="keywordtype">int</span> newCoorX, newCoorY;
<a name="l01504"></a>01504                 <span class="keywordflow">for</span> (dir = 0; dir &lt; 4; dir++)
<a name="l01505"></a>01505                         {
<a name="l01506"></a>01506                         newCoorX = coorX + coorX4Connect[dir];
<a name="l01507"></a>01507                         newCoorY = coorY + coorY4Connect[dir];
<a name="l01508"></a>01508 
<a name="l01509"></a>01509                         <span class="comment">// Check if we are inside the limits in that direction</span>
<a name="l01510"></a>01510                         <span class="keywordflow">if</span> ( (newCoorX &lt; 0) || (newCoorY &lt; 0) || (newCoorX &gt;= ((<span class="keywordtype">int</span>)cols)) || (newCoorY &gt;= ((<span class="keywordtype">int</span>)rows)) )
<a name="l01511"></a>01511                                 <span class="keywordflow">continue</span>;
<a name="l01512"></a>01512 
<a name="l01513"></a>01513                         <span class="comment">// Check if it is a valid direction and if the pixel in that direction is part of a contour</span>
<a name="l01514"></a>01514                         <span class="keywordflow">if</span> ( (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, newCoorX, newCoorY, 0) &gt;= threshold)  &amp;&amp; (lastDir != dir) )
<a name="l01515"></a>01515                                 <span class="keywordflow">break</span>;
<a name="l01516"></a>01516                         }
<a name="l01517"></a>01517 
<a name="l01518"></a>01518                 <span class="keywordflow">if</span> (dir == 4) <span class="keywordflow">break</span>;
<a name="l01519"></a>01519 
<a name="l01520"></a>01520                 coorX = newCoorX;
<a name="l01521"></a>01521                 coorY = newCoorY;
<a name="l01522"></a>01522                 lastDir = (dir+2)%4;
<a name="l01523"></a>01523                 }
<a name="l01524"></a>01524 
<a name="l01525"></a>01525         <span class="keywordflow">return</span> polyline;
<a name="l01526"></a>01526         }
<a name="l01527"></a>01527 
<a name="l01528"></a><a class="code" href="group__qvip.html#ga5dab7ea4ed1170143df3e59fdd895bf9">01528</a> QList&lt;QVPolyline&gt; <a class="code" href="group__qvip.html#ga5dab7ea4ed1170143df3e59fdd895bf9" title="Obtains a list of the 4-connected pixel lines in the imageThis function can be used...">getLineContoursThreshold4Connectivity</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <span class="keyword">const</span> uChar threshold)
<a name="l01529"></a>01529         {
<a name="l01530"></a>01530         <span class="keyword">const</span> uInt cols = image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(), rows = image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>();
<a name="l01531"></a>01531         <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> clone = image;
<a name="l01532"></a>01532 
<a name="l01533"></a>01533         QList&lt;QVPolyline&gt; polylineList;
<a name="l01534"></a>01534 
<a name="l01535"></a>01535         <span class="comment">// Transverse the image</span>
<a name="l01536"></a>01536         <span class="keywordflow">for</span>(uInt col = 0; col &lt; cols; col++)
<a name="l01537"></a>01537                 <span class="keywordflow">for</span>(uInt row = 0; row &lt; rows; row++)
<a name="l01538"></a>01538                         {
<a name="l01539"></a>01539                         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(uChar, clone);
<a name="l01540"></a>01540                         <span class="comment">// If we don&#39;t have an active pixel, continue</span>
<a name="l01541"></a>01541                         <span class="keywordflow">if</span> ( (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(clone, col, row, 0) &lt; threshold) )
<a name="l01542"></a>01542                                 <span class="keywordflow">continue</span>;
<a name="l01543"></a>01543 
<a name="l01544"></a>01544                         <span class="comment">// Else, we compose the contour following two active neighbour pixels:</span>
<a name="l01545"></a>01545                         <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> polyline;
<a name="l01546"></a>01546 
<a name="l01547"></a>01547                         <span class="comment">// We follow first active neighbour pixel, composing the list of pixels in direct order</span>
<a name="l01548"></a>01548                         getLineContourThreshold4Connectivity(clone, QPoint(col, row), polyline, threshold, <span class="keyword">false</span>);
<a name="l01549"></a>01549 
<a name="l01550"></a>01550                         <span class="comment">// Find another neighbour close to the pixel.</span>
<a name="l01551"></a>01551                         uInt dir;                       
<a name="l01552"></a>01552                         <span class="keywordtype">int</span>     newCoorX, newCoorY;
<a name="l01553"></a>01553                         <span class="keywordflow">for</span> (dir = 0; dir &lt; 4; dir++)
<a name="l01554"></a>01554                                 {
<a name="l01555"></a>01555                                 newCoorX = col + coorX4Connect[dir];
<a name="l01556"></a>01556                                 newCoorY = row + coorY4Connect[dir];
<a name="l01557"></a>01557         
<a name="l01558"></a>01558                                 <span class="comment">// Check if we are inside the limits in that direction</span>
<a name="l01559"></a>01559                                 <span class="keywordflow">if</span> ( (newCoorX &lt; 0) || (newCoorY &lt; 0) || (newCoorX &gt;= ((<span class="keywordtype">int</span>)cols)) || (newCoorY &gt;= ((<span class="keywordtype">int</span>)rows)) )
<a name="l01560"></a>01560                                         <span class="keywordflow">continue</span>;
<a name="l01561"></a>01561         
<a name="l01562"></a>01562                                 <span class="comment">// Check if it is a valid direction and if the pixel in that direction is part of a contour</span>
<a name="l01563"></a>01563                                 <span class="keywordflow">if</span> ( (clone(newCoorX, newCoorY) &gt;= threshold) )
<a name="l01564"></a>01564                                         <span class="keywordflow">break</span>;
<a name="l01565"></a>01565                                 }
<a name="l01566"></a>01566 
<a name="l01567"></a>01567                         <span class="comment">// If we found it, add the contour in reverse order.</span>
<a name="l01568"></a>01568                         <span class="keywordflow">if</span> (dir != 4)
<a name="l01569"></a>01569                                 getLineContourThreshold4Connectivity(clone, QPoint(newCoorX, newCoorY), polyline, threshold, <span class="keyword">true</span>);
<a name="l01570"></a>01570 
<a name="l01571"></a>01571                         <span class="comment">// Finally add the polyline to the list.</span>
<a name="l01572"></a>01572                         polylineList.append(polyline);
<a name="l01573"></a>01573                         }
<a name="l01574"></a>01574 
<a name="l01575"></a>01575         <span class="keywordflow">return</span> polylineList;
<a name="l01576"></a>01576         }
<a name="l01577"></a>01577 
<a name="l01579"></a>01579 <span class="comment">// Replicated functions from 4-connected version.</span>
<a name="l01580"></a>01580 <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> getLineContourThreshold8Connectivity(<a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <span class="keyword">const</span> QPoint point, <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> &amp;polyline, <span class="keyword">const</span> uChar threshold, <span class="keywordtype">bool</span> reverse)
<a name="l01581"></a>01581         {
<a name="l01582"></a>01582         <span class="keyword">const</span> uInt cols = image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(), rows = image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>();
<a name="l01583"></a>01583         <a class="code" href="group__qvip.html#ga42904f931068a3ea3f6bdb90861d1dc1" title="Initializes image to be written or read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_WRITE</a>(uChar, image);
<a name="l01584"></a>01584 
<a name="l01585"></a>01585         uInt lastDir = 666, coorX = point.x(), coorY = point.y();
<a name="l01586"></a>01586 
<a name="l01587"></a>01587         qDebug() &lt;&lt; <span class="stringliteral">&quot;\tContour: new contour&quot;</span>;
<a name="l01588"></a>01588 
<a name="l01589"></a>01589         <span class="keywordtype">bool</span> continueCond = <span class="keyword">true</span>;
<a name="l01590"></a>01590         <span class="keywordflow">while</span>(continueCond)
<a name="l01591"></a>01591                 {
<a name="l01592"></a>01592                 qDebug() &lt;&lt; <span class="stringliteral">&quot;\tContour:\tAppending point (&quot;</span> &lt;&lt; coorX &lt;&lt; <span class="stringliteral">&quot;, &quot;</span> &lt;&lt; coorY &lt;&lt; <span class="stringliteral">&quot;)&quot;</span>;
<a name="l01593"></a>01593                 <span class="keywordflow">if</span> (reverse)
<a name="l01594"></a>01594                         polyline.prepend(QPoint(coorX, coorY));
<a name="l01595"></a>01595                 <span class="keywordflow">else</span>
<a name="l01596"></a>01596                         polyline.append(QPoint(coorX, coorY));
<a name="l01597"></a>01597 
<a name="l01598"></a>01598                 <a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, coorX, coorY, 0) = 0;
<a name="l01599"></a>01599 
<a name="l01600"></a>01600                 <span class="comment">// Buscamos un píxel en los vecinos 4 conectados.</span>
<a name="l01601"></a>01601                 uInt dir;
<a name="l01602"></a>01602                 <span class="keywordtype">int</span> newCoorX, newCoorY;
<a name="l01603"></a>01603                 <span class="keywordflow">for</span> (dir = 0; dir &lt; 4; dir++)
<a name="l01604"></a>01604                         {
<a name="l01605"></a>01605                         newCoorX = coorX + coorX4Connect[dir];
<a name="l01606"></a>01606                         newCoorY = coorY + coorY4Connect[dir];
<a name="l01607"></a>01607 
<a name="l01608"></a>01608                         <span class="comment">// Check if we are inside the limits in that direction</span>
<a name="l01609"></a>01609                         <span class="keywordflow">if</span> ( (newCoorX &lt; 0) || (newCoorY &lt; 0) || (newCoorX &gt;= ((<span class="keywordtype">int</span>)cols)) || (newCoorY &gt;= ((<span class="keywordtype">int</span>)rows)) )
<a name="l01610"></a>01610                                 <span class="keywordflow">continue</span>;
<a name="l01611"></a>01611 
<a name="l01612"></a>01612                         <span class="comment">// Check if it is a valid direction and if the pixel in that direction is part of a contour</span>
<a name="l01613"></a>01613                         <span class="keywordflow">if</span> ( (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, newCoorX, newCoorY, 0) &gt;= threshold)  &amp;&amp; (lastDir != dir) )
<a name="l01614"></a>01614                                 <span class="keywordflow">break</span>;
<a name="l01615"></a>01615                         }
<a name="l01616"></a>01616 
<a name="l01617"></a>01617                 <span class="keywordflow">if</span> (dir == 4) 
<a name="l01618"></a>01618                         {
<a name="l01619"></a>01619                         <span class="comment">// Buscamos un píxel en los vecinos 4 conectados diagonalmente.</span>
<a name="l01620"></a>01620                         uInt dir;
<a name="l01621"></a>01621                         <span class="keywordtype">int</span> newCoorX, newCoorY;
<a name="l01622"></a>01622                         <span class="keywordflow">for</span> (dir = 0; dir &lt; 4; dir++)
<a name="l01623"></a>01623                                 {
<a name="l01624"></a>01624                                 newCoorX = coorX + coorX4Diag[dir];
<a name="l01625"></a>01625                                 newCoorY = coorY + coorY4Diag[dir];
<a name="l01626"></a>01626         
<a name="l01627"></a>01627                                 <span class="comment">// Check if we are inside the limits in that direction</span>
<a name="l01628"></a>01628                                 <span class="keywordflow">if</span> ( (newCoorX &lt; 0) || (newCoorY &lt; 0) || (newCoorX &gt;= ((<span class="keywordtype">int</span>)cols)) || (newCoorY &gt;= ((<span class="keywordtype">int</span>)rows)) )
<a name="l01629"></a>01629                                         <span class="keywordflow">continue</span>;
<a name="l01630"></a>01630         
<a name="l01631"></a>01631                                 <span class="comment">// Check if it is a valid direction and if the pixel in that direction is part of a contour</span>
<a name="l01632"></a>01632                                 <span class="keywordflow">if</span> ( (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(image, newCoorX, newCoorY, 0) &gt;= threshold)  &amp;&amp; (lastDir != dir) )
<a name="l01633"></a>01633                                         <span class="keywordflow">break</span>;
<a name="l01634"></a>01634                                 }
<a name="l01635"></a>01635                         <span class="keywordflow">if</span> (dir == 4) <span class="keywordflow">break</span>;
<a name="l01636"></a>01636 
<a name="l01637"></a>01637                         coorX = newCoorX;
<a name="l01638"></a>01638                         coorY = newCoorY;
<a name="l01639"></a>01639                         lastDir = (dir+2)%4;
<a name="l01640"></a>01640                         }
<a name="l01641"></a>01641                 <span class="keywordflow">else</span>    {
<a name="l01642"></a>01642                         coorX = newCoorX;
<a name="l01643"></a>01643                         coorY = newCoorY;
<a name="l01644"></a>01644                         lastDir = (dir+2)%4;
<a name="l01645"></a>01645                         }
<a name="l01646"></a>01646                 }
<a name="l01647"></a>01647 
<a name="l01648"></a>01648         <span class="keywordflow">return</span> polyline;
<a name="l01649"></a>01649         }
<a name="l01650"></a>01650 
<a name="l01651"></a><a class="code" href="group__qvip.html#ga804db01dcec15dce0c303ed4a4715bd6">01651</a> QList&lt;QVPolyline&gt; <a class="code" href="group__qvip.html#ga804db01dcec15dce0c303ed4a4715bd6" title="Obtains a list of the 8-connected pixel lines in the imageThis function can be used...">getLineContoursThreshold8Connectivity</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> &amp;image, <span class="keyword">const</span> uChar threshold)
<a name="l01652"></a>01652         {
<a name="l01653"></a>01653         <span class="keyword">const</span> uInt cols = image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(), rows = image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>();
<a name="l01654"></a>01654         <a class="code" href="classQVImage.html">QVImage&lt;uChar&gt;</a> clone = image;
<a name="l01655"></a>01655 
<a name="l01656"></a>01656         QList&lt;QVPolyline&gt; polylineList;
<a name="l01657"></a>01657 
<a name="l01658"></a>01658         <span class="comment">// Transverse the image</span>
<a name="l01659"></a>01659         <span class="keywordflow">for</span>(uInt col = 0; col &lt; cols; col++)
<a name="l01660"></a>01660                 <span class="keywordflow">for</span>(uInt row = 0; row &lt; rows; row++)
<a name="l01661"></a>01661                         {
<a name="l01662"></a>01662                         <a class="code" href="group__qvip.html#gac7c7fd9f827d54495e9e3bc1993f1bcb" title="Initializes image to be read with macro QVIMAGE_PIXEL.">QVIMAGE_INIT_READ</a>(uChar, clone);
<a name="l01663"></a>01663                         <span class="comment">// If we don&#39;t have an active pixel, continue</span>
<a name="l01664"></a>01664                         <span class="keywordflow">if</span> ( (<a class="code" href="group__qvip.html#ga5dd8ae5ae995f7889bda84469e5465d3" title="Access an image pixel for inspection or modification.">QVIMAGE_PIXEL</a>(clone, col, row, 0) &lt; threshold) )
<a name="l01665"></a>01665                                 <span class="keywordflow">continue</span>;
<a name="l01666"></a>01666 
<a name="l01667"></a>01667                         <span class="comment">// Else, we compose the contour following two active neighbour pixels:</span>
<a name="l01668"></a>01668                         <a class="code" href="classQVPolyline.html" title="Polyline representation.">QVPolyline</a> polyline;
<a name="l01669"></a>01669 
<a name="l01670"></a>01670                         <span class="comment">// We follow first active neighbour pixel, composing the list of pixels in direct order</span>
<a name="l01671"></a>01671                         getLineContourThreshold8Connectivity(clone, QPoint(col, row), polyline, threshold, <span class="keyword">false</span>);
<a name="l01672"></a>01672 
<a name="l01673"></a>01673                         <span class="comment">// Find another neighbour close to the pixel, in 4 connected neighbours</span>
<a name="l01674"></a>01674                         uInt dir;                       
<a name="l01675"></a>01675                         <span class="keywordtype">int</span>     newCoorX, newCoorY;
<a name="l01676"></a>01676                         <span class="keywordflow">for</span> (dir = 0; dir &lt; 4; dir++)
<a name="l01677"></a>01677                                 {
<a name="l01678"></a>01678                                 newCoorX = col + coorX4Connect[dir];
<a name="l01679"></a>01679                                 newCoorY = row + coorY4Connect[dir];
<a name="l01680"></a>01680         
<a name="l01681"></a>01681                                 <span class="comment">// Check if we are inside the limits in that direction</span>
<a name="l01682"></a>01682                                 <span class="keywordflow">if</span> ( (newCoorX &lt; 0) || (newCoorY &lt; 0) || (newCoorX &gt;= ((<span class="keywordtype">int</span>)cols)) || (newCoorY &gt;= ((<span class="keywordtype">int</span>)rows)) )
<a name="l01683"></a>01683                                         <span class="keywordflow">continue</span>;
<a name="l01684"></a>01684         
<a name="l01685"></a>01685                                 <span class="comment">// Check if it is a valid direction and if the pixel in that direction is part of a contour</span>
<a name="l01686"></a>01686                                 <span class="keywordflow">if</span> ( (clone(newCoorX, newCoorY) &gt;= threshold) )
<a name="l01687"></a>01687                                         <span class="keywordflow">break</span>;
<a name="l01688"></a>01688                                 }
<a name="l01689"></a>01689 
<a name="l01690"></a>01690                         <span class="comment">// If we found it, add the contour in reverse order.</span>
<a name="l01691"></a>01691                         <span class="keywordflow">if</span> (dir != 4)
<a name="l01692"></a>01692                                 getLineContourThreshold8Connectivity(clone, QPoint(newCoorX, newCoorY), polyline, threshold, <span class="keyword">true</span>);
<a name="l01693"></a>01693                         <span class="keywordflow">else</span>    {
<a name="l01694"></a>01694                                 <span class="comment">// Find another neighbour close to the pixel, in diagonal connected neighbours</span>
<a name="l01695"></a>01695                                 uInt dir;                       
<a name="l01696"></a>01696                                 <span class="keywordtype">int</span>     newCoorX, newCoorY;
<a name="l01697"></a>01697                                 <span class="keywordflow">for</span> (dir = 0; dir &lt; 4; dir++)
<a name="l01698"></a>01698                                         {
<a name="l01699"></a>01699                                         newCoorX = col + coorX4Diag[dir];
<a name="l01700"></a>01700                                         newCoorY = row + coorY4Diag[dir];
<a name="l01701"></a>01701                 
<a name="l01702"></a>01702                                         <span class="comment">// Check if we are inside the limits in that direction</span>
<a name="l01703"></a>01703                                         <span class="keywordflow">if</span> ( (newCoorX &lt; 0) || (newCoorY &lt; 0) || (newCoorX &gt;= ((<span class="keywordtype">int</span>)cols)) || (newCoorY &gt;= ((<span class="keywordtype">int</span>)rows)) )
<a name="l01704"></a>01704                                                 <span class="keywordflow">continue</span>;
<a name="l01705"></a>01705                 
<a name="l01706"></a>01706                                         <span class="comment">// Check if it is a valid direction and if the pixel in that direction is part of a contour</span>
<a name="l01707"></a>01707                                         <span class="keywordflow">if</span> ( (clone(newCoorX, newCoorY) &gt;= threshold) )
<a name="l01708"></a>01708                                                 <span class="keywordflow">break</span>;
<a name="l01709"></a>01709                                         }
<a name="l01710"></a>01710         
<a name="l01711"></a>01711                                 <span class="comment">// If we found it, add the contour in reverse order.</span>
<a name="l01712"></a>01712                                 <span class="keywordflow">if</span> (dir != 4)
<a name="l01713"></a>01713                                         getLineContourThreshold8Connectivity(clone, QPoint(newCoorX, newCoorY), polyline, threshold, <span class="keyword">true</span>);
<a name="l01714"></a>01714                                 }
<a name="l01715"></a>01715 
<a name="l01716"></a>01716                         <span class="comment">// Finally add the polyline to the list.</span>
<a name="l01717"></a>01717                         polylineList.append(polyline);
<a name="l01718"></a>01718                         }
<a name="l01719"></a>01719 
<a name="l01720"></a>01720         <span class="keywordflow">return</span> polylineList;
<a name="l01721"></a>01721         }
<a name="l01722"></a>01722 
<a name="l01723"></a><a class="code" href="group__qvip.html#ga0a73e3730368b307c874e53dd5af54c4">01723</a> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> <a class="code" href="group__qvip.html#ga0a73e3730368b307c874e53dd5af54c4" title="Applies a fast Laplace filter on the input image.">FastLaplaceFilter</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> image)
<a name="l01724"></a>01724         {
<a name="l01725"></a>01725         <span class="keyword">const</span> <span class="keywordtype">int</span>       cols = image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(),
<a name="l01726"></a>01726                                 rows = image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>();
<a name="l01727"></a>01727 
<a name="l01728"></a>01728         <span class="keywordflow">if</span> ( (cols == 0) or (rows == 0) )
<a name="l01729"></a>01729                 <span class="keywordflow">return</span> image;
<a name="l01730"></a>01730 
<a name="l01731"></a>01731         <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> result(cols, rows);
<a name="l01732"></a>01732 
<a name="l01733"></a>01733         <span class="comment">// Result image and intermediate pointers.</span>
<a name="l01734"></a>01734         <span class="keyword">const</span> <span class="keywordtype">int</span>       srcStep = image.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>(),
<a name="l01735"></a>01735                                 dstStep = result.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>();
<a name="l01736"></a>01736         <span class="keyword">const</span> uChar     *srcData = image.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>();
<a name="l01737"></a>01737         uChar           *dstData = result.<a class="code" href="classQVImage.html#a231507d781e33e508fac771b5284c3c9" title="Method to obtain image data buffer, in read/write mode.">getWriteData</a>(),
<a name="l01738"></a>01738                                 *bottomDstRowData = dstData + (rows-1) * dstStep;
<a name="l01739"></a>01739 
<a name="l01740"></a>01740         <span class="comment">// Set top and bottom marging to zero.</span>
<a name="l01741"></a>01741         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j = 0; j &lt; cols; j++)
<a name="l01742"></a>01742                 dstData[j] = bottomDstRowData[j] = 0;
<a name="l01743"></a>01743 
<a name="l01744"></a>01744         <span class="comment">// Evaluate smooth pixels inside the margings.</span>
<a name="l01745"></a>01745         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = 1; i &lt; rows-1; i++)
<a name="l01746"></a>01746                 {
<a name="l01747"></a>01747                 <span class="keyword">const</span> uChar     *srcRowData = srcData + i * srcStep;
<a name="l01748"></a>01748                 uChar           *dstRowData = dstData + i * dstStep;
<a name="l01749"></a>01749 
<a name="l01750"></a>01750                 <span class="comment">// Set zero left and right margin.</span>
<a name="l01751"></a>01751                 dstRowData[0] = dstRowData[cols-1] = 0;
<a name="l01752"></a>01752 
<a name="l01753"></a>01753                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j = 1; j &lt; cols-1; j++)
<a name="l01754"></a>01754                         {
<a name="l01755"></a>01755                         <span class="keyword">const</span> <span class="keywordtype">int</span> value = int(srcRowData[j]);
<a name="l01756"></a>01756                         <span class="keyword">const</span> <span class="keywordtype">int</span> neighbour1 = int(srcRowData[j - 1]);
<a name="l01757"></a>01757                         <span class="keyword">const</span> <span class="keywordtype">int</span> neighbour2 = int(srcRowData[j + 1]);
<a name="l01758"></a>01758                         <span class="keyword">const</span> <span class="keywordtype">int</span> neighbour3 = int(srcRowData[j - srcStep]);
<a name="l01759"></a>01759                         <span class="keyword">const</span> <span class="keywordtype">int</span> neighbour4 = int(srcRowData[j + srcStep]);
<a name="l01760"></a>01760                         <span class="keyword">const</span> <span class="keywordtype">int</span> minus = neighbour1 + neighbour2 + neighbour3 + neighbour4;
<a name="l01761"></a>01761 
<a name="l01762"></a>01762                         dstRowData[j] = ABS( (value &lt;&lt; 2) - minus);
<a name="l01763"></a>01763                         }
<a name="l01764"></a>01764                 }
<a name="l01765"></a>01765 
<a name="l01766"></a>01766         <span class="keywordflow">return</span> result;
<a name="l01767"></a>01767         }
<a name="l01768"></a>01768 
<a name="l01769"></a><a class="code" href="group__qvip.html#ga69cc8d72179389d9897aa9ac97d62c33">01769</a> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> <a class="code" href="group__qvip.html#ga69cc8d72179389d9897aa9ac97d62c33" title="Applies a fast smooth filter on the input image.">FastSmoothFilter</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> image, <span class="keyword">const</span> uChar threshold)
<a name="l01770"></a>01770         {
<a name="l01771"></a>01771         <span class="keyword">const</span> <span class="keywordtype">int</span>       cols = image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(),
<a name="l01772"></a>01772                                 rows = image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>();
<a name="l01773"></a>01773 
<a name="l01774"></a>01774         <span class="keywordflow">if</span> ( (cols == 0) or (rows == 0) )
<a name="l01775"></a>01775                 <span class="keywordflow">return</span> image;
<a name="l01776"></a>01776 
<a name="l01777"></a>01777         <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> result(cols, rows);
<a name="l01778"></a>01778 
<a name="l01779"></a>01779         <span class="comment">// Result image and intermediate pointers.</span>
<a name="l01780"></a>01780         <span class="keyword">const</span> <span class="keywordtype">int</span>       srcStep = image.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>(),
<a name="l01781"></a>01781                                 dstStep = result.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>();
<a name="l01782"></a>01782         <span class="keyword">const</span> uChar     *srcData = image.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>();
<a name="l01783"></a>01783         uChar           *dstData = result.<a class="code" href="classQVImage.html#a231507d781e33e508fac771b5284c3c9" title="Method to obtain image data buffer, in read/write mode.">getWriteData</a>(),
<a name="l01784"></a>01784                                 *bottomDstRowData = dstData + (rows-1) * dstStep;
<a name="l01785"></a>01785 
<a name="l01786"></a>01786         <span class="comment">// Set top and bottom marging to zero.</span>
<a name="l01787"></a>01787         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j = 0; j &lt; cols; j++)
<a name="l01788"></a>01788                 dstData[j] = bottomDstRowData[j] = 0;
<a name="l01789"></a>01789 
<a name="l01790"></a>01790         <span class="comment">// Evaluate smooth pixels inside the margings.</span>
<a name="l01791"></a>01791         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = 1; i &lt; rows-1; i++)
<a name="l01792"></a>01792                 {
<a name="l01793"></a>01793                 <span class="keyword">const</span> uChar     *srcRowData = srcData + i * srcStep;
<a name="l01794"></a>01794                 uChar           *dstRowData = dstData + i * dstStep;
<a name="l01795"></a>01795 
<a name="l01796"></a>01796                 <span class="comment">// Set zero left and right margin.</span>
<a name="l01797"></a>01797                 dstRowData[0] = dstRowData[cols-1] = 0;
<a name="l01798"></a>01798 
<a name="l01799"></a>01799                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j = 1; j &lt; cols-1; j++)
<a name="l01800"></a>01800                         {
<a name="l01801"></a>01801                         <span class="keyword">const</span> <span class="keywordtype">int</span> value = int(srcRowData[j]);
<a name="l01802"></a>01802 
<a name="l01803"></a>01803                         <span class="keywordflow">if</span> (value &lt; threshold)
<a name="l01804"></a>01804                                 {
<a name="l01805"></a>01805                                 dstRowData[j] = 0;
<a name="l01806"></a>01806                                 <span class="keywordflow">continue</span>;
<a name="l01807"></a>01807                                 }
<a name="l01808"></a>01808 
<a name="l01809"></a>01809                         dstRowData[j] = ( (value &lt;&lt; 1)
<a name="l01810"></a>01810                                                                                         + <span class="keywordtype">int</span>(srcRowData[j - 1])
<a name="l01811"></a>01811                                                                                         + int(srcRowData[j + 1])
<a name="l01812"></a>01812                                                                                         + int(srcRowData[j - srcStep])
<a name="l01813"></a>01813                                                                                         + int(srcRowData[j + srcStep]) ) / 6;
<a name="l01814"></a>01814                         }
<a name="l01815"></a>01815                 }
<a name="l01816"></a>01816 
<a name="l01817"></a>01817         <span class="keywordflow">return</span> result;
<a name="l01818"></a>01818         }
<a name="l01819"></a>01819 
<a name="l01820"></a><a class="code" href="group__qvip.html#ga083ddecc2c02b1aa32bd2dd9d6c69601">01820</a> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> <a class="code" href="group__qvip.html#ga083ddecc2c02b1aa32bd2dd9d6c69601" title="Applies a smooth filter on the input image.">SmoothFilter</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> image, <span class="keyword">const</span> uChar threshold)
<a name="l01821"></a>01821         {
<a name="l01822"></a>01822         <span class="keyword">const</span> <span class="keywordtype">int</span>       cols = image.<a class="code" href="classQVImage.html#ad0f2758702ee4d96d538aa353ae81bb7" title="Overloaded function from QVGenericImage::getCols().">getCols</a>(),
<a name="l01823"></a>01823                                 rows = image.<a class="code" href="classQVImage.html#a55e71ad628f450ee82bb4226cb62ec17" title="Overloaded function from QVGenericImage::getRows().">getRows</a>();
<a name="l01824"></a>01824 
<a name="l01825"></a>01825         <span class="keywordflow">if</span> ( (cols == 0) or (rows == 0) )
<a name="l01826"></a>01826                 <span class="keywordflow">return</span> image;
<a name="l01827"></a>01827 
<a name="l01828"></a>01828         <span class="comment">// Result image and intermediate pointers.</span>
<a name="l01829"></a>01829         <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> result(cols, rows);
<a name="l01830"></a>01830         <span class="keyword">const</span> <span class="keywordtype">int</span>       srcStep = image.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>(),
<a name="l01831"></a>01831                                 dstStep = result.<a class="code" href="classQVImage.html#a8c5cb45d0c7fbf135d89c5cb40ed4875" title="Overloaded function from QVGenericImage::getStep().">getStep</a>();
<a name="l01832"></a>01832         <span class="keyword">const</span> uChar     *srcData = image.<a class="code" href="classQVImage.html#a200b9b19dbe2a79f75d603f9ecc67bf1" title="Method to obtain image data buffer, in read mode.">getReadData</a>();
<a name="l01833"></a>01833         uChar           *dstData = result.<a class="code" href="classQVImage.html#a231507d781e33e508fac771b5284c3c9" title="Method to obtain image data buffer, in read/write mode.">getWriteData</a>(),
<a name="l01834"></a>01834                                 *bottomDstRowData = dstData + (rows-1) * dstStep;
<a name="l01835"></a>01835 
<a name="l01836"></a>01836         <span class="comment">// Set top and bottom marging to zero.</span>
<a name="l01837"></a>01837         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j = 0; j &lt; cols; j++)
<a name="l01838"></a>01838                 dstData[j] = bottomDstRowData[j] = 0;
<a name="l01839"></a>01839 
<a name="l01840"></a>01840         <span class="comment">// Evaluate smooth pixels inside the margings.</span>
<a name="l01841"></a>01841         <span class="keywordflow">for</span>(<span class="keywordtype">int</span> i = 1; i &lt; rows-1; i++)
<a name="l01842"></a>01842                 {
<a name="l01843"></a>01843                 <span class="keyword">const</span> uChar     *srcRowData = srcData + i * srcStep;
<a name="l01844"></a>01844                 uChar           *dstRowData = dstData + i * dstStep;
<a name="l01845"></a>01845 
<a name="l01846"></a>01846                 <span class="comment">// Set zero left and right margin.</span>
<a name="l01847"></a>01847                 dstRowData[0] = dstRowData[cols-1] = 0;
<a name="l01848"></a>01848 
<a name="l01849"></a>01849                 <span class="keywordflow">for</span>(<span class="keywordtype">int</span> j = 1; j &lt; cols-1; j++)
<a name="l01850"></a>01850                         {
<a name="l01851"></a>01851                         <span class="keyword">const</span> <span class="keywordtype">int</span> value = int(srcRowData[j]);
<a name="l01852"></a>01852 
<a name="l01853"></a>01853                         <span class="keywordflow">if</span> (value &lt; threshold)
<a name="l01854"></a>01854                                 {
<a name="l01855"></a>01855                                 dstRowData[j] = 0;
<a name="l01856"></a>01856                                 <span class="keywordflow">continue</span>;
<a name="l01857"></a>01857                                 }
<a name="l01858"></a>01858 
<a name="l01859"></a>01859                         dstRowData[j] = ( (value &lt;&lt; 2)
<a name="l01860"></a>01860                                                                 + (<span class="keywordtype">int</span>(srcRowData[j - 1]) &lt;&lt; 1)
<a name="l01861"></a>01861                                                                 + (<span class="keywordtype">int</span>(srcRowData[j + 1]) &lt;&lt; 1)
<a name="l01862"></a>01862                                                                 + (<span class="keywordtype">int</span>(srcRowData[j - srcStep]) &lt;&lt; 1)
<a name="l01863"></a>01863                                                                 + (<span class="keywordtype">int</span>(srcRowData[j + srcStep]) &lt;&lt; 1)
<a name="l01864"></a>01864 
<a name="l01865"></a>01865                                                                 + <span class="keywordtype">int</span>(srcRowData[j - 1 - srcStep])
<a name="l01866"></a>01866                                                                 + int(srcRowData[j + 1 - srcStep])
<a name="l01867"></a>01867                                                                 + int(srcRowData[j - 1 + srcStep])
<a name="l01868"></a>01868                                                                 + int(srcRowData[j + 1 + srcStep])
<a name="l01869"></a>01869                                                                 ) &gt;&gt; 4;
<a name="l01870"></a>01870                         }
<a name="l01871"></a>01871                 }
<a name="l01872"></a>01872 
<a name="l01873"></a>01873         <span class="keywordflow">return</span> result;
<a name="l01874"></a>01874         }
<a name="l01875"></a>01875 
<a name="l01876"></a><a class="code" href="group__qvip.html#gab0e45b1b85498b4df9cbd1af432cbaea">01876</a> QList&lt;QPointF&gt; <a class="code" href="group__qvip.html#gab0e45b1b85498b4df9cbd1af432cbaea" title="Detects salient points in the Laplace response of an input image.">FastLaplacePoints</a>(<span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> &amp;image, <span class="keyword">const</span> <span class="keywordtype">int</span> threshold, <span class="keyword">const</span> <span class="keywordtype">bool</span> applyPreviousSmooth, <span class="keyword">const</span> <span class="keywordtype">bool</span> smoothResponseImage)
<a name="l01877"></a>01877         {
<a name="l01878"></a>01878         <span class="keyword">const</span> <a class="code" href="classQVImage.html">QVImage&lt;uChar, 1&gt;</a> laplaceImage = <a class="code" href="group__qvip.html#ga0a73e3730368b307c874e53dd5af54c4" title="Applies a fast Laplace filter on the input image.">FastLaplaceFilter</a>(applyPreviousSmooth?<a class="code" href="group__qvip.html#ga69cc8d72179389d9897aa9ac97d62c33" title="Applies a fast smooth filter on the input image.">FastSmoothFilter</a>(image):image);
<a name="l01879"></a>01879 
<a name="l01880"></a>01880         <span class="keywordflow">return</span> getLocalExtremaPixels(smoothResponseImage?<a class="code" href="group__qvip.html#ga69cc8d72179389d9897aa9ac97d62c33" title="Applies a fast smooth filter on the input image.">FastSmoothFilter</a>(laplaceImage, threshold):laplaceImage, threshold);
<a name="l01881"></a>01881         }
<a name="l01882"></a>01882 
<a name="l01883"></a>01883 
<a name="l01884"></a>01884 
</pre></div></div>
</td></tr></table>

<br /><hr><br />
<center><a href="http://perception.inf.um.es/QVision">QVision framework</a>.
<a href="http://perception.inf.um.es">PARP research group</a>.
Copyright &copy; 2007, 2008, 2009, 2010, 2011.</center>
<br />
</body>
</html>
